Leetcode 题解 - 数组与矩阵

这篇博客介绍了多个 LeetCode 上关于数组和矩阵的编程题目,包括将数组中的 0 移动到末尾、改变矩阵维度、找出最长连续 1、有序矩阵查找、找到有序矩阵的第 k 个元素、解决数组中重复和丢失的数、找数组中重复的数、计算数组相邻差值、数组的度、对角元素相等的矩阵、处理嵌套数组以及如何分隔数组使其有序。每个问题都提供了相关题目链接和解题思路。
摘要由CSDN通过智能技术生成

参考:https://github.com/CyC2018/CS-Notes

1. 把数组中的 0 移到末尾

283. Move Zeroes (Easy)

Leetcode / 力扣

For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0].
class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int idx = 0;
        for(auto num : nums){
            if(num!=0)
                nums[idx++] = num;
        }
        while(idx<nums.size())
            nums[idx++] = 0;
    }
};

2. 改变矩阵维度

566. Reshape the Matrix (Easy)

Leetcode / 力扣

Input:
nums =
[[1,2],
 [3,4]]
r = 1, c = 4

Output:
[[1,2,3,4]]

Explanation:
The row-traversing of nums is [1,2,3,4]. The new reshaped matrix is a 1 * 4 matrix, fill it row by row by using the previous list.
class Solution {
public:
    vector<vector<int>> matrixReshape(vector<vector<int>>& nums, int r, int c) {
        int m = nums.size(), n = nums[0].size();
        if(m * n != r * c) return nums;

        vector<vector<int>> res(r, vector<int>(c));
        for(int i=0; i<r; ++i){
            for(int j=0; j<c; ++j){
                int k = i * c + j;
                res[i][j] = nums[k/n][k%n];
            }    
        }

        // for(int i=0; i<m; ++i){
        //     for(int j=0; j<n; ++j){
        //         int k=i*n +j;
        //         res[k/c][k%c] = nums[i][j];
        //     }
        // }
        return res;
        
    }
};

3. 找出数组中最长的连续 1

485. Max Consecutive Ones (Easy)

Leetcode / 力扣

class Solution {
public:
    int findMaxConsecutiveOnes(vector<int>& nums) {
        int max_val = 0, cur = 0;
        for(auto a: nums){
           cur = a==1? cur+1:0;
           max_val = max(max_val, cur);
        }
        return max_val;
    }
};

4. 有序矩阵查找

240. Search a 2D Matrix II (Medium)

Leetcode / 力扣

[
   [ 1,  5,  9],
   [10, 11, 13],
   [12, 13, 15]
]
class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        if(matrix.size()==0 || matrix[0].size()==0) return false;
        int m= matrix.size(), n = matrix[0].size();
        int row=0, col=n-1;
        while(row<m && col>=0){
            if(target==matrix[row][col]) return true;
            else if(target<matrix[row][col]) --col;
            else ++row;
        }
        return false;
    }
};

5. 有序矩阵的 Kth Element

378. Kth Smallest Element in a Sorted Matrix ((Medium))

Leetcode / 力扣

matrix = [
  [ 1,  5,  9],
  [10, 11, 13],
  [12, 13, 15]
],
k = 8,

return 13.

��题参考:[Share my thoughts and Clean Java Code

Leetcode / 力扣

二分查找解法:

class Solution {
public:
    int kthSmallest(vector<vector<int>>& matrix, int k) {
        int m = matrix.size(), n=matrix[0].size();
        int low=matrix[0][0], high=matrix[m-1][n-1];
        while(low <=high){
            int mid = low + (high - low)/2;
            int cnt = 0;
            for(int i=0; i<m; ++i)
                for(int j=0; j<n&&mid>=matrix[i][j]; ++j)
                    ++cnt;
            if(cnt<k) low = mid+1;
            else high = mid-1;
        }
        return low;
    }
};

堆解法:

class Solution {
public:
    int kthSmallest(vector<vector<int>>& matrix, int k) {
        int m=matrix.size(), n=matrix[0].size();

        priority_queue<int, vector<int>, less<int>> q;
        for(int i=0; i<m; ++i){
            for(int j=0; j<n; ++j){
                if(k>0){
                    k--;
                    q.push(matrix[i][j]);
                    continue;
                }
                q.push(matrix[i][j]);
                q.pop();
            }
        }
        return q.top();
    }
};

6. 一个数组元素在 [1, n] 之间,其中一个数被替换为另一个数,找出重复的数和丢失的数

645. Set Mismatch (Easy)

Leetcode / 力扣

Input: nums = [1,2,2,4]
Output: [2,3]

Input: nums = [1,2,2,4]
Output: [2,3]

最直接的方法是先对数组进行排序,这种方法时间复杂度为 O(NlogN)。本题可以以 O(N) 的时间复杂度、O(1) 空间复杂度来求解。

主要思想是通过交换数组元素,使得数组上的元素在正确的位置上。

class Solution {
public:
    vector<int> findErrorNums(vector<int>& nums) {
        int n = nums.size();
        for(int i=0; i<n; ++i){
            while(nums[i]-1!=i && nums[i] != nums[nums[i]-1])
                swap(nums[i], nums[nums[i]-1]);
        }

        for(int i=0; i<n; ++i){
            if(nums[i] != i+1)
                return {nums[i], i+1};
        }
        return {};
    }
};

类似题目:

[448. Find All Numbers Disappeared in an Array (Easy)

Leetcode,寻找所有丢失的元�) / 力扣,寻找所有丢失的元�)
[442. Find All Duplicates in an Array (Medium)

Leetcode,寻找所有重复的元素�) / 力扣,寻找所有重复的元素�)

7. 找出数组中重复的数,数组值在 [1, n] 之间

287. Find the Duplicate Number (Medium)

Leetcode / 力扣

要求不能修改数组,也不能使用额外的空间。

二分查找解法:

class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        int low =1, high = nums.size()-1;
        while(low<high){
            int mid = low + (high-low)/2;
            int cnt = 0;
            for(auto a : nums)
                if(a<=mid) ++cnt;
            if(cnt>mid) high = mid;
            else low = mid+1;
        }
        return low;
    }
};

双指针解法,类似于有环链表中找出环的入口:

class Solution {
public:
    // floyd判环算法
    int findDuplicate(vector<int>& nums) {
        int slow=0, fast=0, t=0;
        while(true){
            slow = nums[slow];
            fast = nums[nums[fast]];
            if(slow==fast) break;
        }
        while(true){
            slow=nums[slow];
            t=nums[t];
            if(slow==t) break;
        }
        return slow;
    }
};

8. 数组相邻差值的个数

667. Beautiful Arrangement II (Medium)

Leetcode / 力扣

Input: n = 3, k = 2
Output: [1, 3, 2]
Explanation: The [1, 3, 2] has three different positive integers ranging from 1 to 3, and the [2, 1] has exactly 2 distinct integers: 1 and 2.

题目描述:数组元素为 1~n 的整数,要求构建数组,使得相邻元素的差值不相同的个数为 k。

让前 k+1 个元素构建出 k 个不相同的差值,序列为:1 k+1 2 k 3 k-1 … k/2 k/2+1.

class Solution {
public:
    vector<int> constructArray(int n, int k) {
        vector<int> res;
        int i=1, j=n;
        while(i<=j){
            if(k>1) res.push_back(k-- % 2 ? i++: j--);
            else res.push_back(i++);
        }
        return res;
    }
};

9. 数组的度

697. Degree of an Array (Easy)

Leetcode / 力扣

Input: [1,2,2,3,1,4,2]
Output: 6

题目描述:数组的度定义为元素出现的最高频率,例如上面的数组度为 3。要求找到一个最小的子数组,这个子数组的度和原数组一样。

class Solution {
public:
    int findShortestSubArray(vector<int>& nums) {
        int n=nums.size(), degree=0, res=INT_MAX;

        unordered_map<int, int> m;
        unordered_map<int, pair<int, int>> pos;
        for(int i=0; i<n; ++i){
            if(++m[nums[i]] == 1)
                pos[nums[i]] = {i, i};
            else
                pos[nums[i]].second = i;
            degree = max(degree, m[nums[i]]);
        }
            
        for(auto a : m)
            if(degree==a.second)
                res = min(res, pos[a.first].second - pos[a.first].first+1);
        return res;
    }
};

10. 对角元素相等的矩阵

766. Toeplitz Matrix (Easy)

Leetcode / 力扣

1234
5123
9512

In the above grid, the diagonals are "[9]", "[5, 5]", "[1, 1, 1]", "[2, 2, 2]", "[3, 3]", "[4]", and in each diagonal all elements are the same, so the answer is True.

class Solution {
public:
    bool isToeplitzMatrix(vector<vector<int>>& matrix) {
        int m=matrix.size(), n=matrix[0].size();
        for(int i=0; i<m; ++i){
            for(int j=0; j<n; ++j){
                if(i>0 && j>0 && matrix[i][j]!=matrix[i-1][j-1])
                    return false;
            }
        }
        return true;

    }
};

11. 嵌套数组

565. Array Nesting (Medium)

Leetcode / 力扣

Input: A = [5,4,0,3,1,6,2]
Output: 4
Explanation:
A[0] = 5, A[1] = 4, A[2] = 0, A[3] = 3, A[4] = 1, A[5] = 6, A[6] = 2.

One of the longest S[K]:
S[0] = {A[0], A[5], A[6], A[2]} = {5, 6, 2, 0}

题目描述:S[i] 表示一个集合,集合的第一个元素是 A[i],第二个元素是 A[A[i]],如此嵌套下去。求最大的 S[i]。

class Solution {
public:
    int arrayNesting(vector<int>& nums) {
        int n=nums.size();
        int max_len = 0;
        
        for(int i=0; i<n; ++i){
           int cur = 0;
           for(int j=i; nums[j]!=-1;){
               cur++;
               int t = nums[j];
               nums[j] = -1;
               j = t;

           } 
           max_len = max(max_len, cur);
        }
        return max_len;
    }
};

12. 分隔数组

769. Max Chunks To Make Sorted (Medium)

Leetcode / 力扣

Input: arr = [1,0,2,3,4]
Output: 4
Explanation:
We can split into two chunks, such as [1, 0], [2, 3, 4].
However, splitting into [1, 0], [2], [3], [4] is the highest number of chunks possible.

题目描述:分隔数组,使得对每部分排序后数组就为有序。

class Solution {
public:
    int maxChunksToSorted(vector<int>& arr) {
        int right=arr[0], n=arr.size(), cnt=0;
        for(int i=0; i<n; ++i){
            right = max(right, arr[i]);
            if(right==i){
                ++cnt;
            }
        }
        return cnt;
    }
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值