1 数组累加和问题三连
知识点补充:系统设计类题目
设计一个系统,该系统的功能是可以一直不停的提供不同的UUID,该UUID使用的极为频繁,比如全球卖西瓜的,每个西瓜子是一个UUID
思路,如果使用hashcode,有可能会产生碰撞。不使用hashcode,使用机器的ip或者mac地址加上纳秒时间,也不行,所有机器时间是否强同步
解决思路:定义一台服务器,对世界的国家进行分类,比如中国下是省份,美国下是州,英国下是邦。每一个国家向中央服务器要随机范围,中央服务器分配出去的是start和range。比如给中国分配的是start从1开始,range到100w,中国uuid不够用了,可以再向中央服务器要,分配后中央服务器的start要增大到已分配出去后的位置。其他国家类似
该设计师垂直扩展的技术,当前很多有事水平扩展,比如直接hashcode,random等。但有些场景适合用这种垂直扩展的解决方案
1.1 数组累加和问题
1.1.1 第一连例题--------------325
有一个全是正数的数组,和一个正数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,此时的窗口大小就是一个满足条件的子数组大小,决定是否要更新答案;
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