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

今日主要题目

977.有序数组的平方

209.长度最小的子数组

59.螺旋矩阵

主要学习网址

代码随想录

做题思路与具体代码

题目一 977.有序数组的平方

做题思路

本题采用双指针的做法

1.左右两个指针分别在数组的最左侧和最右侧开始移动

2.定义一个新数组存放结果集

3.该数组是从小到大,所以最左侧和最右侧的平方才是最大的,所以要从新数组的最左边插入

4.比较左右指针所在位置的值的平方,大的那边就先放入结果数组的最右边

(等于其实放哪个都可以,移动哪个也都可以)

5.放入结果数组后,需要将该指针向中间靠拢,结果数组的指针也得向左走

6.循环是左指针小于等于右指针

具体代码
class Solution {
    public int[] sortedSquares(int[] nums) {
        // 初始化左右指针
       int i=0;
       int j=nums.length-1;
       //  初始化结果数组
       int[] result =new int[nums.length];
       //  初始化结果指针
       int k=nums.length-1;
    //    左右指针向中间靠拢
    while(i<=j){
        if(nums[i]*nums[i]<nums[j]*nums[j]){
            // 右边指针所在位置的值的平方大于左边指针所在位置的值的平方
            // j指针所在位置平方放在结果指针所在位置,j指针移动,结果指针移动
            result[k]=nums[j]*nums[j];
            k--;
            j--;
        }
        //其他条件
        // 两种情况:
        // 1.右边指针所在位置的值的平方小于左边指针所在位置的值的平方
        // 2.右边指针所在位置的值的平方等于左边指针所在位置的值的平方
        // 一样解决方法
        else{
            // i指针所在位置平方放在结果指针所在位置,i指针移动,结果指针移动
            result[k]=nums[i]*nums[i];
            k--;
            i++;
        }
    }
        return result;
    }
}

题目二  209.长度最小的子数组

做题思路

本题思路类似双指针+前缀和

可以用暴力,但是超时,这里不做展示

1.定义起点指针和结束指针

2.结束指针不断往前走,直到结束指针与起点指针之间值的和大于目标值

3.此时结束指针不懂,在while循环中起点指针不断接近结束指针,找到满足条件,但是区间段的长度最小,找到最小的那个值

4.直到区间段的和又重新小于目标值,跳出循环,

注意事项:

其中的结果要初始化为数组的最大值,有利于做判断

具体代码
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        //   初始化起点指针和终点指针
        int i=0;
        int j=0;
        //初始化终点指针与起点指针之间区间的和
        int sum=0;
        //    初始化返回结果
        //    设置为数组最大值
        int result=Integer.MAX_VALUE;
        //     终点指针不断向右走
        for(;j<=nums.length-1;j++){
        //  终点指针与起点指针之间值的和
            sum+=nums[j];
        //  当和大于等于目标值时,就开始将起点指针不断向右移动缩小,知道找到满足条件的最小的区间长度
        //  j-i+1就是这个区间长度
            while(sum>=target){
                result=Math.min(result,j-i+1);
                sum-=nums[i];
                i++;
            }
        }
        //要是结果还是最大值的话,就证明没有满足条件的,就直接返回0
        return result == Integer.MAX_VALUE ? 0 : result;
    }
}

题目三   59.螺旋矩阵

本题思路

本题思路采用循环,主要思路包括左闭右开,4个流程比如:

从左往右、从上往下、从右往左、从下往上

按照顺序不断循环(顺序很重要)

1.首先初始化循环的圈数从0开始(为了后面这个写法while(loop++<n/2)做准备)

2.初始化不断改变位置的i和j

3.定义循环的开始点和用来填充新数组的数字count

4.记住得定义新的二维数组

5.从左往右:

这时候需要初始化j=start,因为start会根据圈数不同而改变

j到运行到n-loop的位置,随着圈数的增加,j运行的范围就越来越小

再把值不断赋给新的二维数组

6,从上往下:

这时候j就不用变了,但是i需要初始化为start,因为start会根据圈数不同而改变

i同样运行到n-loop的位置,随着圈数的增加,i运行的范围就越来越小

7.从右往左:

这时候i和j的值都不需要初始化了,在原有基础上修改就好,i不变,j不断向左走

走到loop的位置(我们一开始初始化走的位置是0,loop现在是1,还是符合左闭右开的原则的)

8.从下往上

这时候i和j的值都不需要初始化了,在原有基础上修改就好,j不变,i不断向上走

走到loop的位置(我们一开始初始化走的位置是0,loop现在是1,还是符合左闭右开的原则的)

(边界问题要处理好)

9.走完一圈了,start得加1,就是新的一圈起始位置加1了,新的起始位置是(1,1)不再是(0,0)

起始位置也就是这个循环圈的头

10.最后最后注意一个问题,我们默认旋转的圈数是n/2圈,但是如果是奇数圈,中间就会多出一个中间点,所以要加上去res[start][start]=count++;

此时start就是最后这个点圈的起始点也是唯一点

11.返回结果二维数组

具体代码
class Solution {
    public int[][] generateMatrix(int n) {
    //初始化已经循环的圈数,从0开始
    //为什么是从0开始,因为后面用到了loop++<n/2
    int loop=0;
    //从左往右
    //从上往下
    //从右往左
    //从下往上
    //定义循环的开始点(start,start)=(0,0)
    int start=0;
    //初始化返回数组
    int res[][]=new int[n][n];
    //初始化填充数字
    int count=1;
    //初始化循环用到的i,j
    int i,j;
    //按圈数循环
    //这里loop++简化了开发,不用一直在后面写上loop++,但是有个问题,loop初始值需要为0
    while(loop++<n/2){
        //从左往右
        //x为初始位置,y为j向右移动,遵循左闭右开的原则,直到到达边界n-loop
        for(j=start;j<n-loop;j++){
              res[start][j]=count++;
        }
        //从上往下
        //y为j已经移动到的位置,x为i向下移动
        for(i=start;i<n-loop;i++){
              res[i][j]=count++;
        }
        //从右往左
        //此时不必初始化值因为,i和j都已经初始化了并且走了一些距离了
        //y为j向左走,走到loop位置,loop位置代表圈数比如1,可以走到1
        for(;j>=loop;j--){
              res[i][j]=count++;
        }
        //从下往上
        //x为i向上走,走到loop位置,loop位置代表圈数比如1,可以走到1
        for(;i>=loop;i--){
              res[i][j]=count++;
        }
        //走完一圈了,初始值位置改变
        start++;
    }

    //因为转一圈遍历的是两行,所以要除2
    //如果是奇数的话,多出一个中间点
    if(n%2==1){
        res[start][start]=count++;
    }
    return res;
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第二十二天的算法训练主要涵盖了Leetcode题目中的三道题目,分别是Leetcode 28 "Find the Index of the First Occurrence in a String",Leetcode 977 "有序数组的平方",和Leetcode 209 "长度最小的数组"。 首先是Leetcode 28题,题目要求在给定的字符串中找到第一个出现的字符的索引。思路是使用双指针来遍历字符串,一个指向字符串的开头,另一个指向字符串的结尾。通过比较两个指针所指向的字符是否相等来判断是否找到了第一个出现的字符。具体实现的代码如下: ```python def findIndex(self, s: str) -> int: left = 0 right = len(s) - 1 while left <= right: if s[left == s[right]: return left left += 1 right -= 1 return -1 ``` 接下来是Leetcode 977题,题目要求对给定的有序数组中的元素进行平方,并按照非递减的顺序返回结果。这里由于数组已经是有序的,所以可以使用双指针的方法来解决问题。一个指针指向数组的开头,另一个指针指向数组的末尾。通过比较两个指针所指向的元素的绝对值的大小来确定哪个元素的平方应该放在结果数组的末尾。具体实现的代码如下: ```python def sortedSquares(self, nums: List[int]) -> List[int]: left = 0 right = len(nums) - 1 ans = [] while left <= right: if abs(nums[left]) >= abs(nums[right]): ans.append(nums[left ** 2) left += 1 else: ans.append(nums[right ** 2) right -= 1 return ans[::-1] ``` 最后是Leetcode 209题,题目要求在给定的数组中找到长度最小的数组,使得数组的和大于等于给定的目标值。这里可以使用滑动窗口的方法来解决问题。使用两个指针来表示滑动窗口的左边界和右边界,通过移动指针来调整滑动窗口的大小,使得滑动窗口中的元素的和满足题目要求。具体实现的代码如下: ```python def minSubArrayLen(self, target: int, nums: List[int]) -> int: left = 0 right = 0 ans = float('inf') total = 0 while right < len(nums): total += nums[right] while total >= target: ans = min(ans, right - left + 1) total -= nums[left] left += 1 right += 1 return ans if ans != float('inf') else 0 ``` 以上就是第二十二天的算法训练的内容。通过这些题目的练习,可以提升对双指针和滑动窗口等算法的理解和应用能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值