【Leetcode刷题】——Integer Array - 整型数组

1.【LeetCode448】:448. 找到所有数组中消失的数字

题目分析: 1-n之间有重复的,有没出现的,有出现一次。使用hashmap,空间复杂度为O(n)

方法一:哈希表,但是空间复杂度超过了O(n)

思想:

  1. 可以用hashmap存储数据,建立映射。
  2. 从1-n去遍历,看hashmap中有没有出现元素。
  3. 有出现,下一个继续遍历,没有传入数组。

方法二: 使用数组本身,这样空间就不会多用

思想:

  1. 已知元素的范围是1-n,数组下标的范围是0-n-1。从头开始遍历,比如说4,把它转换为对应的下标就是3,把3下标对应的元素变为负数(或者加n),这样就相当于 标记 与下标3对应的数。
  2. 如果某个数我们已经处理过了,这时候就要还原,然后再比较。
  3. 最后再遍历一次,找出没出现过的下标。

示例:

	|
	4 3 2 7 8 2 3 1 
	0 1 2 3 4 5 6 7
遍历:4-1=3,把下标为3的元素前填负号->-7
     3-1=2,把下标为2的元素前填负号->-2
     遍历一遍后,数组变为
     -4 -3 -2 -7 8 2 -3 -1
     所以4和5这对应数字没有出现过,就是5和6没有出现过

image-20220504101957231

题解:

class Solution {
public:
    vector<int> findDisappearedNumbers(vector<int>& nums) {
        int n=nums.size();
        for(int num:nums){
            int x=(num-1)%n;//对n取模还原它本来的值
            nums[x]+=n;//对这个元素加n
        }
        vector<int> ans;
        for(int i=0;i<n;i++){
            if(nums[i]<=n){
                ans.push_back(i+1);
            }
        } 
        return ans; 
    }
};

2【LeetCode48】48. Rotate Image (Medium)

题目分析:要进行原地计算。1.寻找规律 2.按顺序进行旋转操作,避免覆盖原始值。

可以将旋转过程简化为两个翻转操作:

先按照主对角线进行翻转,再左右翻转

image-20220504135434041

题解:

class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        int n = matrix.size();
        for(int i = 0; i<n;i++){
            for(int j=0;j<i;j++){//对交线翻转
                swap(matrix[i][j],matrix[j][i]);
            }
           
        }
         for(int i = 0; i<n;i++){
              for(int j=0;j<n/2;j++){//左右翻转
                swap(matrix[i][j],matrix[i][n-1-j]);
            }
         }
    }
};

3 【LeetCode240】240. Search a 2D Matrix II (Medium)

题目分析:在矩阵中不是边界的点有四个方向,所以我们要从某个边界开始,将四个方向转换为两个方向。这道题从右上或者左下都可以。

image-20220504143255396

题解:

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int m=matrix.size();//行
        int n=matrix[0].size();//列
        if(m==0)    return false;
        // int i=0,j=n-1;//从右上开始搜索
        // while(i<m&&j>=0){
        //     if(matrix[i][j]==target){
        //         return true;
        //     }else if(matrix[i][j]>target){
        //         --j;
        //     }else{
        //         ++i;
        //     }    
        // }

        int i=m-1,j=0;//从左下开始搜索
        while(i>=0&&j<n){
            if(matrix[i][j]==target){
                return true;
            }else if(matrix[i][j]>target){
                --i;
            }else{
                ++j;
            }    
        }
        return false;
    }
};

4 【LeetCode769】:769. Max Chunks To Make Sorted (Medium)

题目分析:因为数组元素的特性,它的元素大小范围是0-n-1(并且不重复),刚好与数组下标对应。

从左往右遍历,同时记录当前的最大值,每当 当前最大值 等于数组位置时,我们可以多一次分割。

为什么可以通过这个算法解决问题呢?

1.如果当前最大值大于数组位置,则说明右边一定有小于数组位置的数字,需要把它也加入待排序的子数组;

2.又因为数组只包含不重复的0 到n,所以当前最大值一定不会小于数组位置。

3.所以每当当前最大值等于数组位置时,说明 当前最大值 之前的值都已经出现过了,可以进行一次划分,对后续划分没有影响。我们可以成功完成一次分割。

image-20220504153750285

题解:

class Solution {
public:
    int maxChunksToSorted(vector<int>& arr) {
       int ans=0;
       int m=0;
       for(int i=0;i<arr.size();++i){
           m=max(m,arr[i]);
           if(m==i) ++ans;
       }
       return ans;
    }
};
posted @ 2022-05-04 16:05  huilinmumu  阅读(102)  评论(0编辑  收藏  举报