您的位置:首页 > 其它

209. Minimum Size Subarray Sum

2016-12-27 09:38 260 查看
*最后更新**

有道云笔记BUG不断,真是好讨厌,对于输入法支持特别差,你见过切了输入法之后不能用方向键的编辑器吗?这个垃圾就是。

关机每次还报错,如果能移植到别的地方,老子早他妈移植了。 我现在还特别怀疑它丢失文件,这个题我的内容二刷一半就没了,不知道是自动保存失败还是就是遗失了,好烦。

三刷(二刷的资料没了)

连续区间,所以不需要DP之类的,用的滑窗,多退少补。

两层逻辑关系没想象的那么直白。

Time: O(n)

public class Solution {
public int minSubArrayLen(int s, int[] nums) {
if (s == 0 || nums.length == 0) return 0;

int right = 0;
int left = 0;
int sum = 0;
int res = Integer.MAX_VALUE;

while (right < nums.length) {

while (right < nums.length && sum < s) {
sum += nums[right++];
}

while (left < right && sum >= s) {
res = Math.min(res, right - left);
sum -= nums[left++];
}

}
if (res == Integer.MAX_VALUE) return 0;
return res;
}
}

看别人的总结,这个Array的题还是利用了单调性,只是不是很明显。

右指针的单调性是它的移动会让总和增加;左指针是减少,所以才会使得我们可以固定一边,排除很多brute force的组合。

一刷

There are 2 ways.

One Time comlexity: n

public class Solution {
public int minSubArrayLen(int s, int[] nums) {
if(nums.length == 0) return 0;

int begin = 0;
int end = 0;

int max = Integer.MAX_VALUE;

int temp = 0;
while(end < nums.length)
{

while(temp < s && end < nums.length)
{
temp = temp + nums[end];
end++;
}

while(temp >= s && begin <= end)
{
max = Math.min(max,end-begin);
temp = temp - nums[begin];
begin++;
}

}

return max == Integer.MAX_VALUE? 0:max;
}
}

Two Time: nlgn

the usual way which is brute force

介入新的ARRAY sum[i] = nums[0]+nums[1]+nums[2]+..+nums[i-1];

brute force 对于NUM每个元素 都再N一次 n²

对于sum每个元素 用binary search nlgn

不好解释 具体自己看。。

public class Solution {
public int minSubArrayLen(int s, int[] nums)
{

if(nums.length == 0 ) return 0;

int length = nums.length;

int[] sum = new int[length+1];
sum[0] = 0;
for(int n = 0; n < length; n++)
{
sum[n+1] = sum
+ nums
;
}

//sum[n+1]
int min = Integer.MAX_VALUE;
for(int m = 0; m < length+1; m++)
{
int left = m;
//System.out.println(sum[m]+s);
int right = search(sum,m+1,length,s);

if(right == length + 1) break;

min = Math.min(min,right-m);

}

return min == Integer.MAX_VALUE? 0:min;
}

public int search(int[] sum, int m, int length,int s)
{
//System.out.println(s+sum[m-1]);
int total = s+sum[m-1];

int left = m;
int right = length;

while(left <= right)
{
int mid = (left + right)/2;
if(sum[mid] >= total)
{
right = mid - 1;
}
else
{
left = mid + 1;
}
}

return left;

}
}

----

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: