- [1 æ°ç»ç´¯å åé®é¢ä¸è¿](#1)
* [1.1 æ°ç»ç´¯å åé®é¢](#11)
+ [1.1.1 第ä¸è¿ä¾é¢](#111)
+ [1.1.2 第äºè¿ä¾é¢](#112)
+ [1.1.2 第ä¸è¿ä¾é¢](#112)
1 æ°ç»ç´¯å åé®é¢ä¸è¿
ç¥è¯ç¹è¡¥å
ï¼ç³»ç»è®¾è®¡ç±»é¢ç®
设计ä¸ä¸ªç³»ç»ï¼è¯¥ç³»ç»çåè½æ¯å¯ä»¥ä¸ç´ä¸åçæä¾ä¸åçUUIDï¼è¯¥UUID使ç¨çæä¸ºé¢ç¹ï¼æ¯å¦å
¨çå西ççï¼æ¯ä¸ªè¥¿ç忝ä¸ä¸ªUUID
> æè·¯ï¼å¦æä½¿ç¨hashcodeï¼æå¯è½ä¼äº§ç碰æãä¸ä½¿ç¨hashcodeï¼ä½¿ç¨æºå¨çipæè
macå°åå ä¸çº³ç§æ¶é´ï¼ä¹ä¸è¡ï¼æææºå¨æ¶é´æ¯å¦å¼ºåæ¥
> è§£å³æè·¯ï¼å®ä¹ä¸å°æå¡å¨ï¼å¯¹ä¸ççå½å®¶è¿è¡åç±»ï¼æ¯å¦ä¸å½ä¸æ¯ç份ï¼ç¾å½ä¸æ¯å·ï¼è±å½ä¸æ¯é¦ãæ¯ä¸ä¸ªå½å®¶åä¸å¤®æå¡å¨è¦éæºèå´ï¼ä¸å¤®æå¡å¨åé
åºå»çæ¯startårangeãæ¯å¦ç»ä¸å½åé
çæ¯startä»1å¼å§ï¼rangeå°100w,ä¸å½uuidä¸å¤ç¨äºï¼å¯ä»¥ååä¸å¤®æå¡å¨è¦ï¼åé
åä¸å¤®æå¡å¨çstartè¦å¢å¤§å°å·²åé
åºå»åçä½ç½®ãå
¶ä»å½å®¶ç±»ä¼¼
> 该设计å¸åç´æ©å±çææ¯ï¼å½åå¾å¤æäºæ°´å¹³æ©å±ï¼æ¯å¦ç´æ¥hashcodeï¼randomçã使äºåºæ¯éåç¨è¿ç§åç´æ©å±çè§£å³æ¹æ¡
1.1 æ°ç»ç´¯å åé®é¢
1.1.1 第ä¸è¿ä¾é¢
æä¸ä¸ªå
¨æ¯æ£æ°çæ°ç»ï¼åä¸ä¸ªæ£æ°sumãæ±è¯¥æ°ç»çç´¯å åçäºsumçåæ°ç»å¤é¿ãä¾å¦[3,2,1,1,1,6,1,1,1,1,1,1],sumçäº6ãæé¿çåæ°ç»ä¸º[1,1,1,1,1,1]è¿åé¿åº¦6
> ç±äºæ¯æ£æ°æ°ç»ï¼ç´¯å ååèå´å
·æåè°æ§ã对äºå
·æåè°æ§çé¢ç®ï¼è¦ä¹å®ä¹å·¦å³æéï¼è¦ä¹å®ä¹çªå£æ»å¨
å®ä¹çªå£window,windowSumåå§ä¸º0ãæ»å¨çè¿ç¨ä¸ï¼
1ã妿windowSumå°äºsumï¼çªå£å³è¾¹çRåå³ç§»å¨ä¸ä¸ªä½ç½®ï¼
2ã妿windowSum大äºsumï¼çªå£å·¦è¾¹çLåå³ç§»å¨ä¸ä¸ªä½ç½®ï¼
3ã妿windowSumçäºsumï¼æ¤æ¶ççªå£å¤§å°å°±æ¯ä¸ä¸ªæ»¡è¶³æ¡ä»¶çåæ°ç»å¤§å°ï¼å³å®æ¯å¦è¦æ´æ°çæ¡ï¼
```Java
public class Code01_LongestSumSubArrayLengthInPositiveArray {
// æ»å¨çªå£ç表示
public static int getMaxLength(int[] arr, int K) {
if (arr == null || arr.length == 0 || K <= 0) {
return 0;
}
// åå§çªå£ä½ç½®[0,0],çªå£å½ååªæç¬¬ä¸ä¸ªæ°
int left = 0;
int right = 0;
int sum = arr[0];
int len = 0;
while (right < arr.length) {
// çªå£çç´¯å åsumçäºæä»¬çç®æ kãæ±çªå£å¤§å°len
if (sum == K) {
len = Math.max(len, right - left + 1);
// çªå£ç´¯å ååå»å·¦çªå£ä½ç½®çå¼ï¼å·¦ä½ç½®ååºçªå£
sum -= arr[left++];
} else if (sum < K) {
// çªå£å³è¾¹çæ©ï¼å¦æä¸è¶çææ©ä¹åçé£ä¸ªä½ç½®çå¼å å°çªå£ç´¯å å¼ä¸
right++;
if (right == arr.length) {
break;
}
sum += arr[right];
} else {
sum -= arr[left++];
}
}
return len;
}
// for test
public static int right(int[] arr, int K) {
int max = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = i; j < arr.length; j++) {
if (valid(arr, i, j, K)) {
max = Math.max(max, j - i + 1);
}
}
}
return max;
}
// for test
public static boolean valid(int[] arr, int L, int R, int K) {
int sum = 0;
for (int i = L; i <= R; i++) {
sum += arr[i];
}
return sum == K;
}
// for test
public static int[] generatePositiveArray(int size, int value) {
int[] ans = new int[size];
for (int i = 0; i != size; i++) {
ans[i] = (int) (Math.random() * value) + 1;
}
return ans;
}
// for test
public static void printArray(int[] arr) {
for (int i = 0; i != arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
public static void main(String[] args) {
int len = 50;
int value = 100;
int testTime = 500000;
System.out.println("test begin");
for (int i = 0; i < testTime; i++) {
int[] arr = generatePositiveArray(len, value);
int K = (int) (Math.random() * value) + 1;
int ans1 = getMaxLength(arr, K);
int ans2 = right(arr, K);
if (ans1 != ans2) {
System.out.println("Oops!");
printArray(arr);
System.out.println("K : " + K);
System.out.println(ans1);
System.out.println(ans2);
break;
}
}
System.out.println("test end");
}
}
```
1.1.2 第äºè¿ä¾é¢
æä¸ä¸ªæ°ç»ï¼å¼å¯ä»¥ä¸ºæ£å¯ä»¥ä¸ºè´å¯ä»¥ä¸º0ãç»å®ä¸ä¸ªå¼sumï¼æ±åæ°ç»ä¸ç´¯å åçäºsumçæå¤§é¿åº¦ï¼
> 该é¢å第ä¸è¿é®é¢çåºå«æ¯ï¼æ°ç»çå¼å¯æ£å¯è´å¯é¶ï¼åè°æ§æ¶å¤±äºãå¯¹äºæ°ç»é®é¢ï¼æä»¬å¸¸è§çè§£å³åæ°ç»çæèæè·¯ï¼å¦æä»¥æ¯ä¸ä¸ªä½ç½®å¼å¤´è½æ±åºä¸ä¸ªçæ¡ï¼é£ä¹ç®æ çæ¡ä¸å®å¨å
¶ä¸ãåè¿æ¥å¦æä»¥æ¯ä¸ä¸ªä½ç½®ä¸ºç»å°¾è½æ±åºä¸ä¸ªçæ¡ï¼é£ä¹ç®æ çæ¡ä¸å®ä¹å¨å
¶ä¸
> è¯¥é¢æè·¯ç¨ç¬¬äºç§æ¯è¾æ¹ä¾¿ï¼æä»¬ä»¥æä¸ªä½ç½®iç»å°¾ï¼ä¹åçæ°ç´¯å åçäºç®æ sumï¼æ±è¯¥ä½ç½®æ»¡è¶³æ¤æ¡ä»¶çæé¿æ°ç»ãè¯¥ç§æè·¯çåäºï¼ä»0ä½ç½®å¼å§å°iä½ç½®çç´¯å åï¼allSumï¼ï¼åå»ä»0ä½ç½®å°ææ©å0ä½ç½®çç´¯å åçäºallSum-sumçä½ç½®jãé£ä¹åé®é¢ççæ¡æ¯j+1å°jä½ç½®çé¿åº¦ãé¢ç½®ï¼0ä½ç½®ç´¯å åä½ç½®çäº-1ä½ç½®
```Java
public class Code02_LongestSumSubArrayLength {
// arræ°ç»ï¼ç´¯å å为kçæé¿åæ°ç»è¿å
public static int maxLength(int[] arr, int k) {
if (arr == null || arr.length == 0) {
return 0;
}
// key表示累å åï¼valueè¡¨ç¤ºææ©åºç°çä½ç½®
HashMap map = new HashMap();
// 0ä½ç½®çç´¯å åï¼ææ©åºç°å¨-1ä½ç½®ãé¢ç½®
map.put(0, -1); // important
// æå¤§é¿åº¦æ¯å¤å°
int len = 0;
// ç´¯å åå¤å¤§
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
if (map.containsKey(sum - k)) {
// j+1å°iæå¤å°ä¸ªæ°ï¼i-j个
len = Math.max(i - map.get(sum - k), len);
}
if (!map.containsKey(sum)) {
map.put(sum, i);
}
}
return len;
}
// for test
public static int right(int[] arr, int K) {
int max = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = i; j < arr.length; j++) {
if (valid(arr, i, j, K)) {
max = Math.max(max, j - i + 1);
}
}
}
return max;
}
// for test
public static boolean valid(int[] arr, int L, int R, int K) {
int sum = 0;
for (int i = L; i <= R; i++) {
sum += arr[i];
}
return sum == K;
}
// for test
public static int[] generateRandomArray(int size, int value) {
int[] ans = new int[(int) (Math.random() * size) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = (int) (Math.random() * value) - (int) (Math.random() * value);
}
return ans;
}
// for test
public static void printArray(int[] arr) {
for (int i = 0; i != arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
public static void main(String[] args) {
int len = 50;
int value = 100;
int testTime = 500000;
System.out.println("test begin");
for (int i = 0; i < testTime; i++) {
int[] arr = generateRandomArray(len, value);
int K = (int) (Math.random() * value) - (int) (Math.random() * value);
int ans1 = maxLength(arr, K);
int ans2 = right(arr, K);
if (ans1 != ans2) {
System.out.println("Oops!");
printArray(arr);
System.out.println("K : " + K);
System.out.println(ans1);
System.out.println(ans2);
break;
}
}
System.out.println("test end");
}
}
```
å¯¹äºæ°ç»arrï¼å¯æ£å¯è´å¯é¶ãæ±åæ°ç»ä¸1å2æ°å¼ä¸ªæ°ç¸ççåæ°ç»æé¿çé¿åº¦ï¼è¿åï¼
> ææ°ç»ä¸å
¶ä»æ°å¼å为0ï¼ä¸º1çæ°å¼ä»ä¸º1ï¼ä¸º2çæ°å¼å为-1ãå¤ç好ä¹åï¼æ±åæ°ç»ç´¯å å为0çæé¿åæ°ç»ã
> å¾å¤æ°ç»é®é¢ï¼å¯ä»¥è½¬å为æ±åæ°ç»ç´¯å åé®é¢ï¼éè¦è®ç»ææåº¦
1.1.2 第ä¸è¿ä¾é¢
ä¸ä¸ªæ°ç»arrä¸ï¼ææ£æ°ï¼æè´æ°ï¼æ0ãç»å®ç´¯å åç®æ kï¼æ±ææåæ°ç»ç´¯å åä¸å°äºçäºkçæ°ç»çæå¤§é¿åº¦ï¼
æ¦å¿µå®ä¹ï¼
以iå¼å¤´çåæ°ç»ä¸ï¼ææå¯è½æ§ä¸ï¼åªä¸ä¸ªè½è®©ç´¯å åæå°çèå´æ¯ä»ä¹ï¼
ä¾å¦[3,7,4,-6,6,3,-2,0,7-3,2],åå¤ä¸¤ä¸ªè¾
婿°ç»minSum[],minEnd[]ãminSumè®°å½ä»iå¼å§åç»åæ°ç»ä¸ç´¯å åæå°çå¼ãminEndè®°å½iå¼å§åç»åæ°ç»ä¸ç´¯å åæå°çç´¯å åçç»æ¢ä½ç½®j
对äºiä½ç½®ï¼å¦ææåä¸ºæ£æ°ï¼é£ä¹æç´¯å åæå°çå°±æ¯æèªå·±ï¼å¦æèªèº«æ¯æ£æ°ï¼ç´¯å åæå°å°±æ¯æå³ä¾§ä½ç½®è®¡ç®åºæ¥çæå°ç´¯å å
妿¤æä½ï¼ä»»æiä½ç½®ï¼æå°åæ°ç»ç´¯å åæä»¬è½æ¿å°ï¼æå°ç´¯å ååæ°ç»çå³è¾¹çæä»¬è½æ¿å°
> 该é¢å·§å¦ä¹å¤æ¯æé¤å¯è½æ§ï¼æ¯è¾é¾
```Java
public class Code03_LongestLessSumSubArrayLength {
public static int maxLengthAwesome(int[] arr, int k) {
if (arr == null || arr.length == 0) {
return 0;
}
int[] minSums = new int[arr.length];
int[] minSumEnds = new int[arr.length];
minSums[arr.length - 1] = arr[arr.length - 1];
minSumEnds[arr.length - 1] = arr.length - 1;
for (int i = arr.length - 2; i >= 0; i--) {
if (minSums[i + 1] < 0) {
minSums[i] = arr[i] + minSums[i + 1];
minSumEnds[i] = minSumEnds[i + 1];
} else {
minSums[i] = arr[i];
minSumEnds[i] = i;
}
}
int end = 0;
int sum = 0;
int res = 0;
// iæ¯çªå£çæå·¦çä½ç½®ï¼endæ©åºæ¥çæå³ææåå¿çæåä¸ä¸ªä½ç½®çï¼åä¸ä¸ä¸ªä½ç½®
// end乿¯ä¸ä¸åå¿çå¼å§ä½ç½®
// çªå£ï¼[i~end)
for (int i = 0; i < arr.length; i++) {
// while循ç¯ç»æä¹åï¼
// 1) 妿以iå¼å¤´çæ
åµä¸ï¼ç´¯å å<=kçæé¿åæ°ç»æ¯arr[i..end-1]ï¼ççè¿ä¸ªåæ°ç»é¿åº¦è½ä¸è½æ´æ°resï¼
// 2) 妿以iå¼å¤´çæ
åµä¸ï¼ç´¯å å<=kçæé¿åæ°ç»æ¯arr[i..end-1]çï¼æ´æ°è¿æ¯ä¸æ´æ°resé½ä¸ä¼å½±åæç»ç»æï¼
while (end < arr.length && sum + minSums[end] <= k) {
sum += minSums[end];
end = minSumEnds[end] + 1;
}
res = Math.max(res, end - i);
if (end > i) { // çªå£å
è¿ææ° [i~end) [4,4)
sum -= arr[i];
} else { // çªå£å
å·²ç»æ²¡ææ°äºï¼è¯´æä»iå¼å¤´çææåæ°ç»ç´¯å åé½ä¸å¯è½<=k
end = i + 1;
}
}
return res;
}
public static int maxLength(int[] arr, int k) {
int[] h = new int[arr.length + 1];
int sum = 0;
h[0] = sum;
for (int i = 0; i != arr.length; i++) {
sum += arr[i];
h[i + 1] = Math.max(sum, h[i]);
}
sum = 0;
int res = 0;
int pre = 0;
int len = 0;
for (int i = 0; i != arr.length; i++) {
sum += arr[i];
pre = getLessIndex(h, sum - k);
len = pre == -1 ? 0 : i - pre + 1;
res = Math.max(res, len);
}
return res;
}
public static int getLessIndex(int[] arr, int num) {
int low = 0;
int high = arr.length - 1;
int mid = 0;
int res = -1;
while (low <= high) {
mid = (low + high) / 2;
if (arr[mid] >= num) {
res = mid;
high = mid - 1;
} else {
low = mid + 1;
}
}
return res;
}
// for test
public static int[] generateRandomArray(int len, int maxValue) {
int[] res = new int[len];
for (int i = 0; i != res.length; i++) {
res[i] = (int) (Math.random() * maxValue) - (maxValue / 3);
}
return res;
}
public static void main(String[] args) {
System.out.println("test begin");
for (int i = 0; i < 10000000; i++) {
int[] arr = generateRandomArray(10, 20);
int k = (int) (Math.random() * 20) - 5;
if (maxLengthAwesome(arr, k) != maxLength(arr, k)) {
System.out.println("Oops!");
}
}
System.out.println("test finish");
}
}
```