·今日学习的文章链接和视频链接
·自己看到题目的第一想法
(977.有序数组的平方)心里:应该很简单,双指针。实操:在原数组中操作不过来,需要循环判断用到递归,搞不动。(竟然没想到暴力解法!!后面都要先有实现的能力,再用进化版的技能!)
(209.长度最小的子数组)知道判断逻辑,但不会实现。
(59.螺旋矩阵II)无处下手。
·看完代码随想录之后的想法
(977.有序数组的平方)暴力真好,适合自己。双指针也不好用啊,原来要定义新数组!和与新数组对应的索引。原数组双指针:用于循环判断的条件和原数组元素检索。
(209.长度最小的子数组)暴力解法很简洁。滑动窗口内部实现有点绕,不过怎么滑动的在心里有个动图。
果断看视频:
拿下滑动窗口! | LeetCode 209 长度最小的子数组_哔哩哔哩_bilibili
(59.螺旋矩阵II)循环判断,根据图示找规律。
·自己实现过程中遇到哪些困难
(977.有序数组的平方)基础不牢固,数组声明初始化、排序==;思维上不清晰。
(209.长度最小的子数组)对"int ans = Integer.MAX_VALUE;"和"return ans == Integer.MAX_VALUE ? 0 : ans;"两句代码理解不到位,break关键字理解不到位。
(59.螺旋矩阵II)循环几圈?到哪里结束?怎么确定n的奇偶性会影响内部是否有独数?循环区间怎么限定?for循环中i,j之间的联系?
·今日收获,记录一下自己的学习时长
(977.有序数组的平方)很容易掌握暴力解法,双指针开拓思路了。
(209.长度最小的子数组)真正理解并实现了暴力解法及其细节,很开心。学习了关键字break/return/continue的区别,break中止本层循环,return结束该方法,continue中止本次循环。对"int ans = Integer.MAX_VALUE;"和"return ans == Integer.MAX_VALUE ? 0 : ans;"两句代码的作用理解深刻(感谢群友小白耐心解答)。滑动窗口一层for循环,内嵌while判断语句找最小子数组,借助上面两条代码判断数组是否存在sum大于target。
(59.螺旋矩阵II)这道题更多的考点是画图找规律,就硬实现就行。需要注意的实现细节,细节,细节!还有一点是有点考熟练度。
目前应该注重实现完成算法的基础能力!!!定个小目标:训练题目能够暴力实现即可,优化方法尽量掌握。
(977.有序数组的平方) // class Solution { // public int[] sortedSquares(int[] nums) { // //失败版本双指针:存在问题,判断一次不能解决问题,双指针怎么清晰运行,没想清楚!!! // 进一步思考:这种方式好像使用递归,可以解决,但怎么实现。。 // // int s = 0; // // int f = nums.length - 1; // // while (s < f) { // // if (nums[f] * nums[f] > nums[s] * nums[s]) { // // nums[f] = nums[f] * nums[f]; // // f--; // // } else { // // int temp = nums[f]; // // nums[f] = nums[s] * nums[s]; // // nums[s] = temp; // // f--; // // } // // } // // nums[s] = nums[s] * nums[s]; // // return nums; // // 看文章之后的暴力输出,喜欢暴力的方案 // // for (int i = 0; i < nums.length; i++) { // // nums[i] = nums[i] * nums[i]; // // } // // Arrays.sort(nums); // // return nums; // } // } //看文章一点一点修改的双指针,有漏洞。。前半部分没有经过比较排序,所以数组是无序的。 // 步骤:①定义一个等容量的新数组nums1,存放最后的结果,同时定义新数组的索引k:方便从后向前插入数据。②定义原数组左右指针,用于循环判断的条件和原数组元素检索。③比较平方后数值大小,将较大值插入新数组并做k--操作,同时将左右两侧的值对应++或--操作,便于后面循环判断。 // 定义新数组较为关键,想不起来!!想起来之后也应该能想起定义索引下标。 // 定义左右指针,比较之后左右指针的++ --操作 class Solution { public int[] sortedSquares(int[] nums) { int[] nums1 = new int[nums.length]; int k = nums.length - 1; int l = 0, r = nums.length - 1; while (l <= r) { if (nums[r] * nums[r] > nums[l] * nums[l]) { nums1[k] = nums[r] * nums[r]; k--; r--; } else { nums1[k] = nums[l] * nums[l]; k--; l++; } } return nums1; } }
209.长度最小的子数组 // // 两层for循环,第一层确定开始位置,第二层确定结束位置; // // // class Solution { // public int minSubArrayLen(int target, int[] nums) { // if (nums.length == 0) return 0; // int ans = Integer.MAX_VALUE; // 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) { // ans = Math.min(ans, j - i + 1);//ans = Math.min(ans, j - i + 1)的功能是比较当前的ans和j - i + 1的值,然后将较小的值赋给ans。这个功能的作用是在循环中找到最小的长度值。 // break; // } // } // } // return ans == Integer.MAX_VALUE ? 0 : ans;//return ans == Integer.MAX_VALUE ? 0 : ans;的功能是判断ans的值是否等于Integer.MAX_VALUE,如果是,则返回0,否则返回ans的值。这个功能的作用是在没有找到符合条件的最小长度时,返回默认值0 // } // } // 滑动窗口: // 步骤:①定义滑动的索引j,向后遍历数组,求sum;②当sum >= target时进入while (sum >= target)循环判断,while可以找到最小数组长度;③三元运算判断是否存在sum>target,不存在,返回0,存在返回最小子数组长度res。 // 此外,i 和 sum应声明为全局变量,i是为了保证子数组最小长度,sum是保证最小子数组i到j的sum值大于target。这样循环中不需要从0开始,减少不必要的循环。 class Solution { public int minSubArrayLen(int target, int[] nums) { int res = Integer.MAX_VALUE; int i = 0; int sum = 0; for (int j = 0; j < nums.length; j++) { sum += nums[j]; while (sum >= target) { res = Math.min(res, j - i + 1); sum -= nums[i]; i++; } } return res == Integer.MAX_VALUE ? 0 : res; } }
(59.螺旋矩阵II) class Solution { public int[][] generateMatrix(int n) { int loop = 0; int[][] res = new int[n][n]; int start = 0; int count = 1; int i, j; while (loop++ < n / 2) { for (j = start; j < n - loop; j++) { res[start][j] = count++; } for (i = start; i < n - loop; i++) { res[i][j] = count++; } for (; j > start; j--) { res[i][j] = count++; } for (; i > start; i--) { res[i][j] = count++; } start++; } if (n % 2 == 1) { res[start][start] = count; } return res; } }