977.有序数组的平方
题目链接:977.有序数组的平方
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
思路
数组其实是有序的, 只不过最小的负数平方之后可能成为最大数了。
那么数组平方的最大值就在数组的两端,不是最左边就是最右边,不可能是中间。
-
确定循环次数,先准备一个返回结果的数组,每个格子都要填满,次数就是nums.length
-
双指针分别指向头尾,结果集指针指向最后(结果集为升序,最大的元素放最后)
-
比较头尾的平方谁大,大的就放到下面数组最后一个位置(结果数组是升序)
-
将较大的元素指针移动到中间,同时结果集指针向前移
Java实现
public int[] sortedSquares(int[] nums) {
// 双指针
int begin = 0;
int end = nums.length - 1;
// 结果集
int[] result = new int[nums.length];
System.out.println();
for(int i = nums.length - 1; i >= 0; i--) {
// 头尾的平方数
int beginNum = nums[begin] * nums[begin];
int endNum = nums[end] * nums[end];
if(beginNum > endNum) { //头>尾,把头的值给结果集,头往前移
result[i] = beginNum;
begin++;
} else { //头<=尾,把尾的值给结果集,头往前移
result[i] = endNum;
end--;
}
}
return result;
}
209.长度最小的子数组
题目链接:209. 长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其总和大于等于 target 的 长度最小的 子数组[numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
思路
使用双指针构造一个区间。动态判断每个区间是否是最短长度的
以题目中的示例来举例,target=7, 数组是 2,3,1,2,4,3
1、快指针遍历素组,慢指针不动,窗口长度增大。
例如从下图中的[2],移动到[2,3,1,2]
2、当窗口中的值>=target时,快指针停止,慢指针开始往前移动,窗口缩小,同时判断窗口中的元素和是否>=target,如果依然满足,会再往前移动,直到窗口中的值<target。每次慢指针移动时,都会记录窗口长度,看是否为最小长度。
例子如下:
1、当窗口为[2,3,1,2]时,和为7,满足条件,记最小距离为4;
2、索引j停止移动,i开始前移,区间为[3,1,2],不满足条件;
3、索引i停止,j前移,区间为[3,1,2,4];满足条件,此时区间长度为4,与最小距离相同,不做覆盖;
4、索引i停止,j前移,区间为[1,2,4];满足条件,此时区间长度为3,小于最小距离4,进行覆盖;
后续重复上述操作,直到遍历完数组
Java实现
public int minSubArrayLen(int target, int[] nums) {
int begin = 0;
int sum = 0;
int min_len = Integer.MAX_VALUE; //如果初始化为0,下面要先赋值再判断,这个最小长度就无法更新
for(int end = 0; end < nums.length; end++) {
sum += nums[end]; // 更新区间内元素和
while(sum >= target) {
int len = end - begin + 1; // 获取区间长度,索引相减要加1
min_len = min_len > len ? len : min_len; // 判断目前区间长度是否为最小
sum -= nums[begin++]; // 慢指针前移,同时更新区间内元素和
}
}
return min_len == Integer.MAX_VALUE ? 0 : min_len; // 如果元素和一次都不满足条件,返回0
}