【代码随想录算法训练营-第二天】【数组】977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II

977.有序数组的平方

看完思路后一遍AC

  • 思路剖析:
    • 因为提到了时间复杂度为O(n),自然想到只能遍历一遍
    • 又因为只规定了时间复杂度,但是没有规定空间复杂度,所以可以考虑在定义一个数组【这一步没有考虑出来,是看了思路的】
    • 因为前一天做了二分查找,其实是考虑到使用双指针的思想,也在用这个思路思考,但是一直想着在同一个数组之内排序,没有想到重新定一个空的数组;
class Solution {
    public int[] sortedSquares(int[] nums) {
        int[] new_nums = new int[nums.length];
        int i = 0, j = nums.length - 1;
        for (int k = nums.length - 1; k >= 0; k--) {
            if (nums[i] * nums[i] <= nums[j] * nums[j]) {
                new_nums[k] = nums[j] * nums[j];
                j--;
            } else {
                new_nums[k] = nums[i] * nums[i];
                // 这一步一开始写成了i--导致总是 ArrayIndexOutOfBoundsException 
                i++; 
            }
        }
        return new_nums;
    }
}

209.长度最小的子数组

第一遍

  • 思路:判断最小长度,而且要时间复杂度是O(n log(n)),想到这样的话,只能最多for循环一遍,因此想到了双指针的算法;
  • 这一遍写了20mins,打了很多补丁,总是有逻辑上的错误导致代码死循环,因此放弃自己想,看了一下代码随想录;
  • 发现思路是差不多,但区别是:
    • 我是一直通过判断最小的长度来不断更改结果;
    • 随想录里面是通过判断i,j之间的数字之和来不断更改结果;
  • 因此,果断删除现有逻辑,开始着手随想录逻辑;
// 第一遍的错误代码
class Solution {
    public int minSubArrayLen(int[] nums, int target) {
        int min_len = nums.length + 1;
        int i = 0, j = 0;
        while (j < nums.length) {
            int sum = 0;
            for (int k = i; k >= i & k <= j; k++) {
                sum += nums[k];
            }
            if (sum >= target) {
                int tmp_len = j - i + 1;
                if (min_len == tmp_len) {
                    i++;
                    j++;
                    continue;
                }
                min_len = min_len > tmp_len ? j - i++ + 1 : min_len;
            } else {
                j++;
            }
        }
        return min_len == nums.length + 1 ? 0 : min_len;
    }
}

第二遍

  • 写了5mins,AC了;
class Solution {
    public int minSubArrayLen(int[] nums, int target) {
        int min_len = nums.length + 1;
        int i = 0, sum = 0;
        for (int j = 0; j < nums.length; j++) {
            sum += nums[j];
            while (sum >= target) {
                min_len = Math.min(j - i + 1, min_len);
                sum -= nums[i++];
            }
        }
        return min_len == nums.length + 1 ? 0 : min_len;
    }
}

59.螺旋矩阵II

第一遍

  • 思路:第一遍的思路是如何判断每次遍历结束的节点,但是总是会有这样那样的漏洞,补丁打了二十分钟也没有完成思路,于是看了代码随想录;
  • 重点:
    • 循环不变原则,每次总是要保持左闭右开的遍历方式;
    • 学会通过多个参数去保持遍历的准确性;
    • 没有想到可以用循环圈数作为while条件;
    • 代码里面还有一个重点,注释+debug理解起来会更容易比较容易;
import java.util.Arrays;

public class test {
    public static void main(String[] args) {
        int n = 4;
        Solution s = new Solution();
        int[][] result = s.generateMatrix(n);
        for (int i = 0; i < n; i++) {
            System.out.println(Arrays.toString(result[i]));
        }
    }
}

class Solution {
    public int[][] generateMatrix(int n) {
        int[][] result = new int[n][n];
        int loop = 0;
        int i = 0, j = 0;
        int start_x = 0, start_y = 0;
        int offset = 1;
        int count = 1;
        while (loop++ < n / 2) {
            for (j = start_x; j < n - offset; j++) {
                // 这里是一个重点,因为每一轮遍历完,i的位置都是我们接下来要遍历的行数-1,所以需要用starty,我们定义好的行的开始位置
                result[start_y][j] = count++;
            }
            for (i = start_y; i < n - offset; i++) {
                result[i][j] = count++;
            }
            for (; j > start_y; j--) {
                result[i][j] = count++;
            }
            for (; i > start_x; i--) {
                result[i][j] = count++;
            }
            start_x++;
            start_y++;
            offset++;
        }
        if (n % 2 == 1) {
            result[n / 2][n / 2] = count;
        }
        return result;
    }
}

你可能感兴趣的:(代码随想录-力扣刷题,算法,java)