力扣刷题Day2

977 有序数组的平方

题目:力扣

第一反应:

先把每个数组的平方数计算出来,再进行排序

class Solution {
    public int[] sortedSquares(int[] nums) {
        for(int i=0; i<nums.length; i++){
            nums[i] = nums[i]*nums[i];
        }

        Arrays.sort(nums);

        return nums;
    }
}

但是这样的时间复杂度是O(nlogn),不是最优的。

数组本身就是有序的,数组的平方可能会使原来为负数的元素变为最大的。最大的数一定是在两头之中产生,然后往中间移动。

--> 可以考虑双指针法。指向数组的头端和尾端。

创建一个新的数组,从最后开始填入,每次比较头尾的平方大小,将更大的填入并往中间移动。

class Solution {
    public int[] sortedSquares(int[] nums) {
      int left = 0;
      int right = nums.length-1;

      int[] result = new int[nums.length];
      for(int i=nums.length -1; i>=0; i--){
          if(nums[left]*nums[left] >= nums[right]*nums[right]){
              result[i] = nums[left]*nums[left];
              left++;
          }else{
              result[i] = nums[right]*nums[right];
              right --;
          }
      }

      return result;
    }
}

参考资料:代码随想录

209.长度最少的子数组

题目:力扣

使用滑动窗口的思路

窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。

窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了(也就是该缩小了)。

窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。

编写代码时存在的bug:

使用while循环实现滑动窗口 - 一直在循环中

解决办法:使用for循环 - 针对右指针;while - 针对左指针

 public int minSubArrayLen(int target, int[] nums) {
        int left = 0;
        int minL = nums.length+1;

        int value = 0;
        for(int right = 0; right<nums.length; right++){
            value += nums[right];
            while(value >= target){
                minL = Math.min(minL, right - left +1);
                value -= nums[left];
                left++;
            }
        }

        if(minL == nums.length+1){
            return 0;
        }

        return minL;
    }

参考资料:代码随想录

59. 螺旋矩阵

模拟法

难点:如何处理边界问题

两种思路:每次一边填入相同的数,左闭右开;每一次把一行或者一列填满,左闭右闭

实现的是第二种,感觉第一种在计算边界上比较麻烦一些

public int[][] generateMatrix(int n) {
        int[][] result = new int[n][n];

        int insert = 1; //填入表格中的数字
        //设定边界
        int left = 0;
        int top = 0;
        int right = n-1;
        int bottom = n-1;

        //模拟 - 注意左闭右闭
        while(insert <= n*n){
            //从左到右
            for(int i = left; i<=right; i++){
                result[top][i] = insert;
                insert++;
            }
            top++;
            //从上到下
            for(int i= top; i<=bottom; i++){
                result[i][right] = insert;
                insert++;
            }
            right--;
            //从右往左
            for(int i=right; i>=left; i--){
                result[bottom][i] = insert;
                insert++;
            }
            bottom--;
            //从下到上
            for(int i= bottom; i>=top; i--){
                result[i][left] = insert;
                insert++;
            }
            left++;
        }

        return result;

    }

参考资料:

代码随想录
​​​​​​​​​​​
 

力扣

类似题:

54.旋转矩阵

类似方法解题 - 注意是n*m的矩阵,注意边界问题

 public List<Integer> spiralOrder(int[][] matrix) {

        int n = matrix.length;
        int m = matrix[0].length;

        int left = 0;
        int top = 0;
        int right = m -1;
        int bottom = n -1;

        List<Integer> result = new ArrayList<>();
        int count = 0;
        while(count < n*m){
            for(int i=left; i<=right; i++){
                result.add(matrix[top][i]);//最上面一条
                count++;
            }
            top++;

            if(count == n*m) break;

            for(int i=top; i<=bottom; i++){
                result.add(matrix[i][right]);//最右边一条
                count++;
            }
            right--;

            if(count == n*m) break;

            for(int i=right; i>=left; i--){
                result.add(matrix[bottom][i]);//最下面一条
                count++;
            }
            bottom--;

            if(count == n*m) break;

            for(int i=bottom; i>=top; i--){
                result.add(matrix[i][left]);//最左边一条
                count++;
            }
            left++;
        }

        return result;

    }

数组题目总结:

常用的四个方法:

二分法、双指针法、滑动窗口法、模拟法

参考资料:代码随想录

好的,关于力扣刷题C++常用操作,我可以给你一些常见的操作和技巧: 1. 使用 STL 容器和算法库:STL(Standard Template Library)是 C++ 标准库中的一个重要组成部分,包含了许多常用的容器和算法。在力扣刷题中,使用 STL 可以大大提高代码的效率和可读性。例如,vector 可以用来存储动态数组,sort 可以用来排序等等。 2. 使用 auto 关键字:auto 关键字可以自动推导变量类型,可以减少代码量和提高可读性。例如,auto x = 1; 可以自动推导出 x 的类型为 int。 3. 使用 lambda 表达式:lambda 表达式是 C++11 中引入的一种匿名函数,可以方便地定义一些简单的函数对象。在力扣刷题中,使用 lambda 表达式可以简化代码,例如在 sort 函数中自定义比较函数。 4. 使用位运算:位运算是一种高效的运算方式,在力扣刷题中经常会用到。例如,左移运算符 << 可以用来计算 2 的幂次方,右移运算符 >> 可以用来除以 2 等等。 5. 使用递归:递归是一种常见的算法思想,在力扣刷题中也经常会用到。例如,二叉树的遍历、链表的反转等等。 6. 使用 STL 中的 priority_queue:priority_queue 是 STL 中的一个容器,可以用来实现堆。在力扣刷题中,使用 priority_queue 可以方便地实现一些需要维护最大值或最小值的算法。 7. 使用 STL 中的 unordered_map:unordered_map 是 STL 中的一个容器,可以用来实现哈希表。在力扣刷题中,使用 unordered_map 可以方便地实现一些需要快速查找和插入的算法。 8. 使用 STL 中的 string:string 是 STL 中的一个容器,可以用来存储字符串。在力扣刷题中,使用 string 可以方便地处理字符串相关的问题。 9. 注意边界条件:在力扣刷题中,边界条件往往是解决问题的关键。需要仔细分析题目,考虑各种边界情况,避免出现错误。 10. 注意时间复杂度:在力扣刷题中,时间复杂度往往是评判代码优劣的重要指标。需要仔细分析算法的时间复杂度,并尽可能优化代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值