第一章数组

移除元素

快慢指针法核心就是把不等于目标值的元素加入到一个新数组,这里需要注意的是,双指针并不是像暴力算法那样进行向前的覆盖,而是原数组建立一个新数组,low慢指针就是那个新数组,所以所以最后一次快指针扫到2的时候,是没有做任何事的,而如果用暴力覆盖的话,扫到最后这个2是需要进行覆盖的。

双指针,一个去寻找新数组的元素怒,一个去建立新数组

在这里插入图片描述

package Array;


public class yiChuYuanShu {
    public int doublePointRemove (int[] nums, int val){
        int lowp = 0;
        int fastp = 0 ;
        for(;fastp<nums.length; fastp++){
            if(nums[fastp]!=val){
                nums[lowp] = nums[fastp];
                lowp++;
            }
        }
        return lowp;
    }

    public static void main(String[] args) {
        int[] nums = {0,1,2,3,3,0,4,2} ;    // 使用大括号而不是中括号
        int val = 2 ;
        yiChuYuanShu demo = new yiChuYuanShu();
        int point = demo.doublePointRemove(nums,val);
       // System.out.println(point);
        for (int i = 0 ; i < point;i++){
            System.out.print(nums[i]+" ");
        }
    }
}

有序数组平方

核心思想: 数组平方的最大值就在数组的两端,不是最左边就是最右边,不可能是中间。

在这里插入图片描述

package Array;

/**
 * 功能:
 * 作者:RNG·Cryin
 * 日期:2024-05-28 21:34
 */
public class youXuPingFang {

    public static void main(String[] args) {
            int[] nums = {-4,-1,0,3,10};
            youXuPingFang demo = new youXuPingFang();
            int[] newNums = demo.doublePointPingFang(nums);
            for(int num : newNums){
                System.out.println(num);
           }

    }

    public int[] doublePointPingFang(int[]nums){
        int[] newNums = new int[nums.length] ;
        int index = nums.length - 1 ;
        int right = nums.length - 1 ;
        int left = 0 ;
        while(left <= right){
            if(nums[left]*nums[left] > nums[right]*nums[right]){
                newNums[index--] = nums[left]*nums[left];
                left++ ;
            }else {
                newNums[index--] = nums[right]*nums[right];
                right-- ;
            }
        }
        return newNums ;
    }
}

长度最小子数组

暴力解法的思路是,把每个下标为起点的所有子串都遍历一遍,记录长度和加和,随时进行长度更新。两个for循环可以完成遍历。但暴力解法会在力扣中超时?

class Solution {
public:
    int minSubArrayLen(int s, vector<int>& nums) {
        int result = INT32_MAX; // 最终的结果
        int sum = 0; // 子序列的数值之和
        int subLength = 0; // 子序列的长度
        for (int i = 0; i < nums.size(); i++) { // 设置子序列起点为i
            sum = 0;
            for (int j = i; j < nums.size(); j++) { // 设置子序列终止位置为j
                sum += nums[j];
                if (sum >= s) { // 一旦发现子序列和超过了s,更新result
                    subLength = j - i + 1; // 取子序列的长度
                    result = result < subLength ? result : subLength;
                    break; // 因为我们是找符合条件最短的子序列,所以一旦符合条件就break
                }
            }
        }
        // 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
        return result == INT32_MAX ? 0 : result;
    }
};

滑动窗口解法(双指针的一种)

思路,只想用一次for循环的话,就要考虑如何让起始指针移动。动窗口的精妙之处在于根据当前子序列和大小的情况,不断调节子序列的起始位置。从而将O(n^2)暴力解法降为O(n)。

在这里插入图片描述

class Solution {

    // 滑动窗口
    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;
    }
}

螺旋矩阵

左闭右开是这样画的。

在这里插入图片描述

package Array;

/**
 * 功能:
 * 作者:RNG·Cryin
 * 日期:2024-06-03 20:59
 */
public class LuoXuanJuZhen {


    public static void main(String[] args) {
        int n = 5 ;
        LuoXuanJuZhen luoXuanJuZhen = new LuoXuanJuZhen();
        int[][] nums = new int[n][n];
        nums = luoXuanJuZhen.solution(n);
        for (int i = 0 ; i<n;i++){
            for (int j = 0;j<n;j++){
                System.out.print(nums[i][j]+" ");
            }
            System.out.println();
        }

    }

    public int[][] solution(int n){
        int[][] nums = new int[n][n];
        int startx = 0 ;
        int starty = 0 ;
        int offset = 1;
        int loop = n/2 ;
        int i = 0 ;
        int j = 0 ;
        int count = 1 ;
        for (int k=0; k<loop;k++){
            for( j = starty;j < n-offset ; j++ ){
                nums[startx][j] = count++ ;
            }
            for ( i = startx; i < n-offset; i++){
                nums[i][j] = count++ ;
            }
            for(;j > starty ; j--){
                nums[i][j] = count++ ;
            }
            for (;i > startx ; i--){
                nums[i][j] = count++ ;
            }
            startx++;
            starty++;
            offset++;
        }
        if(n%2 != 0) nums[loop][loop] = count ;
       return nums;


    }
}

力扣习题

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值