【无标题】

代码随想录算法训练营第二天 | LeetCode977 有序数组的平方、LeetCode 209 长度最小的子数组、LeetCode 59 螺旋数组Ⅱ


)
数组的特性是在内存中, 数组申请的内存必须是连续的,数组的元素无法实现真正意义上的删除,只能覆盖

LeetCode977 有序数组的平方

题目链接
使用方法: 双指针
思路:在数组所有元素平方之后, 数组中元素大小的走向为先下降后上升,也就是说可以把数组从中间值(第一个大于等于0的点)切开,可以看成两个已经排好序的新数组, 那对数组进行排序, 也就是对两个数组进行顺序。分别用两个指针指向两个数组的最大值进行比较,最大的放进新数组的末尾,然后再对指针进行操作, 继续循环, 直到跳出循环

public int[] sortedSquares(int[] nums) {
        
        // 这是看了代码随想录对应的视频和文章写出的东西
        // 新的数组数值大小走向为先下降后上身
        // 说明数组的最大值只能诞生在数组的两端,而数组的最小值也只能在中间地带产生
        // 我们可以创建一个相同容量大小的新数组,用两个新指针来分别指代数组的头尾,
        // 比较两个指针指代的值的大小,谁大谁就将值赋值给新数组,并使对应的指针指向新址
        // 判断条件为左指针必须小于等于右指针
        // 不用担心赋值过程中新数组会产生越界的情况,因为他的容量和旧数组一致
        int left = 0;
        int right = nums.length-1;
        int newStartIndex = right;
        int[] res = new int[nums.length];
        while(left <= right){
            // 为什么没有判断相等的情况, 因为如果相等的话, 赋值那个指针都一样
            // 这就是细节
            if(nums[left] * nums[left] > nums[right] * nums[right]){
                res[newStartIndex--] = nums[left] * nums[left];
                left++;
            }else{
                res[newStartIndex--]= nums[right] * nums[right];
                right--;
            }
        }

        return res;
        
    }

LeetCode 209 长度最小的子数组

题目链接
使用方法: 滑动窗口
个人感觉应该叫滑动窗帘, 毕竟现实生活中, 应该没有窗口是可以随意变化大小的吧(

public int minSubArrayLen(int target, int[] nums) {
        int result = Integer.MAX_VALUE; // 这个变量用来存储窗口的最小长度
        int left = 0;
        int sum = 0;
        for(int right = 0; right < nums.length; right++){
            sum += nums[right];
            while(sum>= target){
                result = Math.min(result, right - left + 1);
                sum -= nums[left];
                left++;
            }                
        }
        return result ==Integer.MAX_VALUE ? 0 : result;
    }

LeetCode 59 螺旋数组Ⅱ

题目链接
这道题可以把顺时针分解为
从左到右,从上到下, 从右到左, 从下到上四个部分
四个部分对应着4个for循环
循环的圈数取决于输入的数据是不是奇数
loopNumber = n%2 == 1 ? n/2 +1 : n/2

 public int[][] generateMatrix(int n) {
        int[][] res = new int[n][n];
        // 题目的要求是元素要按按照顺时针排列,为了实现顺时针排列, 可以围着新建的二维数组按照顺时针的方向赋值, 每走完一圈,就调整下标,使得下标指向内圈的初始位置,继续循环
        // 可以将顺时针拆解为4个方向,从左到右,从上到下, 从右到左, 从下到上
        // 可以使用4个for循环分别完成对应赋值的操作
        // 新问题来了, 4个for循环的循环区间应该多大,也就是for循环的终止条件是什么
        // 我这里取得是左闭右开
        // 那应该循环多少次才能完成这个程序呢
        // 循环的次数也就是圈的次数,所以循环判断的条件应该是loop = 0 while(loop <3)
        int element = 1;
        int loop = 0;
        int loopnumber = 0; // 循环圈数
        loopnumber = n%2 == 1? n/2 +1 : n/2;
        while(loop < loopnumber ){
            // 从左到右
            for(int i = loop; i <= n - loop - 1; i++){
                res[loop][i] = element;
                element++;
            }
            // 从上到下
            for(int i = loop + 1; i <= n - loop - 1; i++){
                res[i][n-loop-1] = element;
                element++;
            }
            // 从右到左
            for(int i = n-loop -2; i >=loop; i--){
                res[n-loop -1][i] = element;
                element++;
            }
            // 从下到上
            for(int i = n - loop -2;i >loop; i--){
                res[i][loop] = element;
                element++;
            }
            // 外圈已经赋值完毕,更新圈数, 方便循环更新下一个圈
            loop++;
        }
        return res;
    }

今日总结:不要死磕,太难受了,应该每道题定个25分钟, 解不出来就看对应的视频和文章, 要不然太耗时了
对数组中的边界 和滑动窗口有了更深的理解
数组:
数组的特性尤为重要, 数组特有的连续, 特有的"删除"方式, 对应的算法感觉都是建立在数据结构是数组的基础上得出来的
数组中的边界感很有趣

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值