【代码随想录算法训练营Day02】977.有序数组的平方;209.长度最小的子数组;59.螺旋矩阵II;数组总结

Day 2 第一章 数组part02

  • 建议大家先独立做题,然后看视频讲解,然后看文章讲解,然后在重新做一遍题,把题目AC,最后整理成今日当天的博客
  • 拓展题目可以先不做
  • 今日任务
    • 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II ,总结

977.有序数组的平方

1. 思路

🩸血的教训,自己想出一个思路后先别写代码,确定思路后先看看解析思路一样不一样,不一样的话可能会走很长的弯路
🩸一开始想的是先找到中间的最小值,太麻烦了,还是得转变一下思维

//思路正确后自己做版本
public int[] sortedSquares(int[] nums) {  
    int n[] = new int[nums.length];  
    int left = 0;  
    int right = nums.length-1;  
    int slow = nums.length-1;  
    while(left < right){  
        if(Math.abs(nums[left]) > Math.abs(nums[right])){  
            n[slow --] = nums[left] * nums[left];  //赋完值后slow++
            left ++;  
        }else if(Math.abs(nums[left]) == Math.abs(nums[right])){  
            n[slow --] = nums[left] * nums[left];  
            n[slow --] = nums[left] * nums[left];  
            left ++;  
            right --;  
        }else if(Math.abs(nums[left]) < Math.abs(nums[right])){  
            n[slow --] = nums[right] * nums[right];  
            right --;  
        }  
    }  
    if(left == right){  //单独判断到中间左右相等的情况
        n[slow] = nums[left] * nums[left];  
    }  
    return n;  
}

2. 代码优化

  1. while循环中(left <= right)= ,不然会落下中间相等的数,还得单独判断
  2. if判断不需要单独讨论Math.abs(nums[left]) == Math.abs(nums[right])的情况,可以随便先记一个然后拿另一个和剩下的元素进行比较

如动画所示:

跟着这个动画走

//代码随想录里的标准代码
public int[] sortedSquares(int[] nums) {
    int right = nums.length - 1;
    int left = 0;
    int[] result = new int[nums.length];
    int index = result.length - 1;
    while (left <= right) {
        if (nums[left] * nums[left] > nums[right] * nums[right]) {
            // 正数的相对位置是不变的, 需要调整的是负数平方后的相对位置
            result[index--] = nums[left] * nums[left];
            ++left;
        } else {
            result[index--] = nums[right] * nums[right];
            --right;
        }
    }
    return result;
}

209.长度最小的子数组

1. 自己的思路(超时)

public static int minSubArrayLen(int target, int[] nums) {  
    int size = 0;  
    int sum = 0;  
    for(int i = 0; i < nums.length; i ++){  
        int a = i;  
        sum = nums[a];  
        int l = 1;  
        while(sum < target && a < nums.length-1){  
            sum += nums[++ a];  
            l ++;  
        }  
        if(sum < target){  
            l = 0;  
        }else if(size == 0|| l < size) size = l;  
    }  
    return size;  
}

2. 滑动窗口

双指针:一个表示滑动窗口的起始位置,一个表示滑动窗口的终止位置

  1. 先移动终止位置的指针找到一个sum>target的集合
  2. 再移动起始位置指针缩小这个集合
//思路对后自己写的代码
public static int minSubArrayLen(int target, int[] nums) {  
    int size = 0, temp = 0;  
    int sum = 0;  
    int start = 0, end = 0;  
    for(end = 0; end < nums.length; end ++){  
        sum += nums[end];  
        temp ++;  
        while(sum >= target){  
            if(sum - nums[start] < target) break;  
            else{  
                sum -= nums[start++];  
                temp--;  
            }  
        }  
        if(sum < target){  
            size = 0;  
        }else if(size == 0|| temp < size) size = temp;  
    }  
    return size;  
}

3. 代码优化

  1. 不需要设置中间值,也不用每循环一次result++,直接通过right - left + 1计算,通过Math.min()函数取值。通过把result设置成最大整数,只在有值时才给result赋值
  2. if-else判断可以换成条件运算符result == Integer.MAX_VALUE ? 0 : result;
\\代码随想录代码
public int minSubArrayLen(int s, int[] nums) {
    int left = 0;
    int sum = 0;
    int result = Integer.MAX_VALUE;
    for (int right = 0; right < nums.length; right++) {
        sum += nums[right];
        while (sum >= s) {
            result = Math.min(result, right - left + 1);
            sum -= nums[left++];
        }
    }
    return result == Integer.MAX_VALUE ? 0 : result;
}

59.螺旋矩阵II

1. 自己的思路(通过)

pFC61pV.png

代码
public static int[][] generateMatrix(int n) { 
	int a[][] = new int[n][n];  
	int b = 1;  
	int r1 = 0, r2 = n-1;   //定义首行末行  
	int c1 = 0, c2 = n-1;   //定义首列末列  
	while(b<=n*n){  
	    for(int j = c1; j <= c2; j ++){//过程1:上行从做到右 n_n-2_n-4...  a[r1][j] = b ++;  
	    }  
	    r1 ++;  
	    for(int i = r1; i <= r2; i ++){//过程2:右列从上到下 n-1_n-3_n-5...  a[i][c2] = b ++;  
	    }  
	    c2 --;  
	    for(int j = c2; j >= c1; j --){//过程3:下行从右到左 n-1_n-3_n-5...  a[r2][j] = b++;  
	    }  
	    r2 --;  
	    for(int i = r2; i >= r1; i --){//过程4:左列从下到上 n-2_n-4...  a[i][c1] = b++;  
	    }  
	    c1 ++;  
	}  
	return a;  
}

2. 重点

循环不变量原则

代码随想录代码略

总结

其他知识点

Day 2

4. 直接用system.out.println();输出数组乱码

在IDEA中,对于一个数组,如int[] arr = new int[] { 2, 3, 67, 1, 34, 23 };
直接打印是结果是乱码System.out.println(arr);?如[I@b9e45a? 这是怎么回事

那是因为System.out.println这个方法,默认调用的是对象的toString()方法的内容
[I@b9e45a[表示数组,I表示int类型,b9e45a是对象名
这就是int[] arr对象的toString内容。
如果要打印数组,用Arrays这个工具类:

 System.out.println(Arrays.toString(arr));
 System.out.println(Arrays.deepToString(arr)); //二维数组

5. Integer.MAX_VALUE;

Integer.MAX_VALUE表示int数据类型的最大取值数:2 147 483 647 Integer.MIN_VALUE表示int数据类型的最小取值数:-2 147 483 648

  • 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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值