209. 长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
示例 1:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0
提示:
1 <= target <= 109
1 <= nums.length <= 105
1 <= nums[i] <= 105
进阶:
如果你已经实现 O(n) 时间复杂度的解法, 请尝试设计一个 O(n log(n)) 时间复杂度的解法。
-
未看题解之前思路:
是利用指针的思想,先连续两个两个看,每个数依次和下一个数加和,这两个的和是否大于target;若两个两个的没有,就三个三个看,以此类推,最后应该是整个数组长度那么看;但是没写出来代码,难点是怎么控制这两个两个一起活着三个三个等数组进行有范围的累加,因此没做出来。
另一种思路是直接从头暴力的尝试,12,123,1234,12…n、23,234,234…n就把所有情况都加一遍,随后选一个最短的。 -
integer.MAX_VALUE 看题解之前先学一下
整数型和浮点型取值范围如下:
Integer.MAX_VALUE表示int数据类型的最大取值数:2 147 483 647
Integer.MIN_VALUE表示int数据类型的最小取值数:-2 147 483 648
对应:
Short.MAX_VALUE 为short类型的最大取值数 32 767
Short.MIN_VALUE 为short类型的最小取值数 -32 768
其他数据类型同上含义
补充:
Integer.MAX_VALUE+1=Integer.MIN_VALUE
因为:
Integer.MAX_VALUE的二进制是0111 1111 1111 1111 1111 1111 1111 1111
Integer.MIN_VALUE的二进制是 1000 0000 0000 0000 0000 0000 0000 0000
0111 1111 1111 1111 1111 1111 1111 1111+1=1000 0000 0000 0000 0000 0000 0000 0000 -
暴力法(超出时间限制不行)
注意break;语句的使用,如果不用后面将会进行没有必要的计算,因为起始点不动,一直往后加,这个时候应该用break来停止,并从第i+1个数开始 -
库函数Integer.MAX_VALUE;
-
库函数Math.min(an,j-i+1);
class Solution { public int minSubArrayLen(int target, int[] nums) { if (nums.length == 0) { return 0; } int an=Integer.MAX_VALUE; // int re=0; for(int i=0;i<nums.length;i++){ int sum = 0; for(int j=i;j<nums.length;j++){ sum+=nums[j]; if(sum>=target){ an=Math.min(an,j-i+1); break; } } } return an == Integer.MAX_VALUE ? 0 : an; //这里是说没执行for循环an的值没有改变 } }
-
滑动窗口
思路:也是两个指针,区别于暴力法于,这个的复杂度更低
不要以为for里放一个while就以为是O(n^2)啊, 主要是看每一个元素被操作的次数,每个元素在滑动窗后进来操作一次,出去操作一次,每个元素都是被操作两次,所以时间复杂度是 2 × n 也就是O(n)。class Solution { public int minSubArrayLen(int s, int[] nums) { int start = 0; int sum=0; int ans=Integer.MAX_VALUE; for(int i=0;i<nums.length;i++){ sum+=nums[i]; while(sum>=s){ ans = Math.min(ans, i - start + 1); sum -= nums[start]; start++; } } return ans==Integer.MAX_VALUE?0:ans; } }
59. 螺旋矩阵 II(结合回形取数)
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
示例 1:
输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
示例 2:
输入:n = 1
输出:[[1]]
提示:
1 <= n <= 20
-
这个题没懂,看着代码也想不出思路
一直维持左闭右开class Solution { public int[][] generateMatrix(int n) { int l = 0, r = n - 1, t = 0, b = n - 1; int[][] mat = new int[n][n]; int num = 1, tar = n * n; while(num <= tar){ for(int i = l; i <= r; i++) mat[t][i] = num++; // left to right. t++; for(int i = t; i <= b; i++) mat[i][r] = num++; // top to bottom. r--; for(int i = r; i >= l; i--) mat[b][i] = num++; // right to left. b--; for(int i = b; i >= t; i--) mat[i][l] = num++; // bottom to top. l++; } return mat; } }
-
代码随想录解题思路
class Solution { public int[][] generateMatrix(int n) { int loop = 0; // 控制循环次数 int[][] res = new int[n][n]; int start = 0; // 每次循环的开始点(start, start) int count = 1; // 定义填充数字 int i, j; while (loop++ < n / 2) { // 判断边界后,loop从1开始 // 模拟上侧从左到右 for (j = start; j < n - loop; j++) { res[start][j] = count++; } // 模拟右侧从上到下 for (i = start; i < n - loop; i++) { res[i][j] = count++; } // 模拟下侧从右到左 for (; j >= loop; j--) { res[i][j] = count++; } // 模拟左侧从下到上 for (; i >= loop; i--) { res[i][j] = count++; } start++; } if (n % 2 == 1) { res[start][start] = count; } return res; } }