代码随想录算法训练营|数组

数组理论基础

1. 数组是存放在连续内存空间上的相同类型数据的集合,内存地址

2. 数组下标是从0开始的,删除增加的时候需要移动其他元素的地址,

        (1) 删除元素:并不是直接删除,而是将后面的元素往前移动并且覆盖。例如数组{1,2,3,4,5},删除3之后是{1,2,4,5,5},特定的语言可能会进行封装操作

3. 在Java中,二维数组访问每行的第一个元素,可以用arr[0],arr[1]。地址不是连续的

题目一:二分查找

1. 前提:有序数组,没有重复元素

2. 重点是区间的定义,也就是不变量。有两种区间方法:左闭右闭,左闭右开

题目二:移除元素

1. 题目描述:给一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度

2. 解法

(1) 暴力解法:可以实现,用两个for循环,外层for是找到值等于val的元素,内层for是将后面的元素往前覆盖

(2) 双指针:设置快慢指针,快指针遍历整个数组,慢指针用来更新新数组。

题目三:有序数组的平方

1. 题目描述:给一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,按 非递减顺序 排序

2. 用双指针从两头

题目四:长度最小子数组

1. 设置快慢指针实现滑动窗口,遍历快指针

2.要注意的点

(1) ans要设置为最大值ans=Integer.MAX_VALUE,如果ans=0,ans=Math.min(length,ans)=0,所以ans不会更新

(2) 如果选择if(sum>=target),慢指针向右一次就会跳出,因此选择while可以将慢指针右移多次

(3) while中因为刚好是符合长度的子数组,所以先输出子数组长度,更新ans。再尝试右移慢指针

题目五: 螺旋矩阵

1. 题目:给一个正整数 n ,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 

2. 注意的点

(1) while里面是判断,本题是进行n/2次循环,到最内层

(2) 设置每一次循环的起始点为(startx, starty),每次循环完之后(start+1, starty+1)

题目六:最多水的容器

1. 题目:. - 力扣(LeetCode) : 每次移动高度较小的那一个指针

public int maxArea(int[] height) {
         int left=0,right=height.length-1;
        int ans=0,s=0;
        while (left<right){
            s=Math.min(height[left],height[right])*(right-left);
            ans=Math.max(s,ans);
            if (height[left]<height[right])left++;
            else right--;
        }
        return ans;
    }

题目七:轮转数组

1. 题目:. - 力扣(LeetCode)

2. 思路:先都轮转,再轮转(0,k-1)和(k,nums.length-1)

  public void rotate(int[] nums, int k) {
        k%=nums.length;
        reverse(nums,0,nums.length-1);
        reverse(nums,0,k-1);
        reverse(nums,k,nums.length-1);
    }
    public void reverse(int[] nums,int left,int right){
        while (left<right){
            int temp=nums[left];
            nums[left]=nums[right];
            nums[right]=temp;
            left++;
            right--;
        }
    }

题目八:除自身以外数组的乘积

1.题目:. - 力扣(LeetCode)

 public int[] productExceptSelf(int[] nums) {
      int[] ans=new int[nums.length];
        ans[0]=1;
        for (int i=1;i<nums.length;i++){//除自身以外左边数的乘积
            ans[i]=ans[i-1]*nums[i-1];
        }
        int right=1;
        for (int i=nums.length-1;i>=0;i--){
            ans[i]*=right;
            right*=nums[i];//right包含右边所有的乘积
        }
        return ans;
    }

题目九:矩阵置零

1. 题目:73. 矩阵置零 - 力扣(LeetCode)

2. 思路:先遍历一遍数组,标记一下为0的,然后再更新

 public void setZeroes(int[][] matrix) {
         boolean[] row=new boolean[matrix.length];
        boolean[] col=new boolean[matrix[0].length];
        for (int i=0;i<matrix.length;i++){
            for (int j=0;j<matrix[0].length;j++){
                if (matrix[i][j]==0){
                    row[i]=true;
                    col[j]=true;
                }
            }
        }
        for (int i=0;i<matrix.length;i++){
            for (int j=0;j<matrix[0].length;j++){
                if (row[i] || col[j]){
                    matrix[i][j]=0;
                }
            }
        }
    }

题目十:旋转图像

1. 题目:48. 旋转图像 - 力扣(LeetCode)

2. 思路:先水平翻转,再主对角线翻转

class Solution {
    public void rotate(int[][] matrix) {
        int n = matrix.length;
        // 水平翻转
        for (int i = 0; i < n / 2; ++i) {
            for (int j = 0; j < n; ++j) {
                int temp = matrix[i][j];
                matrix[i][j] = matrix[n - i - 1][j];
                matrix[n - i - 1][j] = temp;
            }
        }
        // 主对角线翻转
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < i; ++j) {
                int temp = matrix[i][j];
                matrix[i][j] = matrix[j][i];
                matrix[j][i] = temp;
            }
        }
    }
}

题目十一:搜索二维矩阵

1. 题目:240. 搜索二维矩阵 II - 力扣(LeetCode)

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        int m = matrix.length, n = matrix[0].length;
        int x = 0, y = n - 1;
        while (x < m && y >= 0) {
            if (matrix[x][y] == target) {
                return true;
            }
            if (matrix[x][y] > target) {
                --y;
            } else {
                ++x;
            }
        }
        return false;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值