Algorithm(至少一個算法題)
415. Add Strings
題目描述:兩個用字符串表示的大數相加
解題思路:思路很簡單,每位相加并用一個數表示進位即可
算法優化:每位相加后都是存到一個int數組的某一個位置,int能表示的范圍為-2147483648至2147483647,其實就可以一次多位相加,int表示的最大范圍為10位,為了保證不越界每次9位相加并考慮進位(9個數9個數為一組)。
優化注意點:按照優化的思路,結果數組每個元素的范圍是0-999999999,而且除了最高位的元素,其他元素要補0補齊9位。
優化之后提交leetcode發現擊敗的百分比反而變小了,這個可能是因為優化只優化了空間復雜度,實現起來反而復雜了很多
實現代碼如下:
/**
* 描述:大數相加
* <p>
* 優化點:參考BigInteger源碼
* Created by xuery on 2018/11/25.
*/
public class BigDigitPlus {
public static void main(String[] args) {
BigInteger bigInteger = new BigInteger("12341243124341243412", 10);
System.out.println(optimizeAddStrings("6913259244", "71103343"));
}
/**
* 注意點1:雖然不包括前綴0,但是"0"是要考慮的
* <p>
* bug1: num1.charAt是Character類型,需要轉換為數字:num1.charAt(i)-'0'
* bug2: new String(resultArr,0,len), resultArr為int[],不能這么轉,需要借助StringBuilder
*/
public static String addStrings(String num1, String num2) {
int len = Math.max(num1.length(), num2.length()) + 1;
int carry = 0; //進位
int[] resultArr = new int[len];
int i = num1.length() - 1, j = num2.length() - 1, index = len - 1;
while (i >= 0 || j >= 0) {
if (i < 0) {
resultArr[index--] = (num2.charAt(j) + carry - '0') % 10;
carry = (num2.charAt(j--) + carry - '0') / 10;
} else if (j < 0) {
resultArr[index--] = (num1.charAt(i) + carry - '0') % 10;
carry = (num1.charAt(i--) + carry - '0') / 10;
} else {
resultArr[index--] = (num1.charAt(i) - '0' + num2.charAt(j) - '0' + carry) % 10;
carry = (num1.charAt(i--) - '0' + num2.charAt(j--) - '0' + carry) / 10;
}
}
resultArr[0] = carry;
StringBuilder sb = new StringBuilder(len);
for (int k = 0; k < len; k++) {
if (k == 0 && resultArr[0] == 0) {
continue;
} else {
sb.append(resultArr[k]);
}
}
return sb.toString();
}
/**
* 優化方案:適用于num1,num2的位數特別多的時候
* <p>
* 之前的方案是每次只運算一位,其實可以每次運算多位,resultArr數組位int型,int表示的范圍為-2^31--2^31-1(-2147483648--2147483647)
* 可以表示10位之多,所以可以采用位表示9位運算(10位可能越界)
* 這樣每次運算9位,減少空間消耗,提升計算效率,實際底層也是一位一位運算的,這種提升效率是對于運用層來說的
*/
public static String optimizeAddStrings(String num1, String num2) {
int len = (Math.max(num1.length(), num2.length()) + 1) / 9 + 1;
int[] resultArr = new int[len];
int carry = 0;
//9個為一組
int i = num1.length() - 1, j = num2.length() - 1, index = len - 1;
while (i >= 0 || j >= 0) {
if (i < 0) {
String sN2 = num2.substring(j - 8 > 0 ? j - 8 : 0, j + 1);
resultArr[index--] = (Integer.parseInt(sN2) + carry) % 1000000000;
carry = (Integer.parseInt(sN2) + carry) / 1000000000;
j -= 9;
} else if (j < 0) {
String sN1 = num1.substring(i - 8 > 0 ? i - 8 : 0, i + 1);
resultArr[index--] = (Integer.parseInt(sN1) + carry) % 1000000000;
carry = (Integer.parseInt(sN1) + carry) / 1000000000;
i -= 9;
} else {
//取9位,不夠則有幾位取幾位
String sN1 = num1.substring(i - 8 > 0 ? i - 8 : 0, i + 1);
String sN2 = num2.substring(j - 8 > 0 ? j - 8 : 0, j + 1);
resultArr[index--] = (Integer.parseInt(sN1) + Integer.parseInt(sN2) + carry) % 1000000000;
carry = (Integer.parseInt(sN1) + Integer.parseInt(sN2) + carry) / 1000000000;
i -= 9;
j -= 9;
}
}
if (index >= 0) {
resultArr[index--] = carry;
}
StringBuilder sb = new StringBuilder(len);
boolean zeroLeadFlag = true;
boolean firstNoneZeroFlag = true;
for (int k = 0; k < len; k++) {
if (resultArr[k] != 0) {
zeroLeadFlag = false;
}
if (!zeroLeadFlag) {
//記得補齊9位
if (firstNoneZeroFlag) {
sb.append(resultArr[k]);
firstNoneZeroFlag = false;
} else {
String padZeroStr = padZero(String.valueOf(resultArr[k]));
sb.append(padZeroStr);
}
}
}
return zeroLeadFlag ? "0" : sb.toString();
}
private static String padZero(String s) {
StringBuilder sb = new StringBuilder();
for (int i = s.length(); i < 9; i++) {
sb.append('0');
}
sb.append(s);
return sb.toString();
}
}
Review(閱讀一篇英文文章及讀后感)
繼續微服務相關文章, 參考教程用spring boot自己實現一個簡易的微服務
microservices-with-spring-boot
image.png
- 兩個微服務:CCS(consumer)和FS(provider)
- Feign用于rest請求
- Ribbon采用client-side模式負載均衡(在consumer端配置)
- Eureka Naming Service 用于服務發現(類似于zookeeper)
Tip(一個小技巧)
Logging with Spring Aop(通過Aop攔截器,統一打點方法被調用時的日志)
參考:https://five.agency/logging-with-spring-aop/
雖然一直在使用Spring,但是都是用公司已有框架,正好通過自己編寫一個AOP日志攔截器復習下
Share(心得體會)
share一直不大會寫,分享一下學心理學課看到的一段話:
注意你的思想,因為它將變成言辭;
注意你的言辭,因為它將變成行動;
注意你的行動,因為它將變成習慣;
注意你的習慣,因為它將變成性格;
注意你的性格,因為它將決定你的命運。
早點認識自己,慢慢成為自己,相信我們可以決定自己的命運
所以在平時的生活工作學習中,要完成的事情就立刻去做,不要找借口,行動起來,讓優秀變成一種習慣,讓習慣改善我們的生活,慢慢的改變自己的人生腳本。