参考:https://github.com/CyC2018/CS-Notes
- 1. 把数组中的 0 移到末尾
- 2. 改变矩阵维度
- 3. 找出数组中最长的连续 1
- 4. 有序矩阵查找
- 5. 有序矩阵的 Kth Element
- 6. 一个数组元素在 [1, n] 之间,其中一个数被替换为另一个数,找出重复的数和丢失的数
- 7. 找出数组中重复的数,数组值在 [1, n] 之间
- 8. 数组相邻差值的个数
- 9. 数组的度
- 10. 对角元素相等的矩阵
- 11. 嵌套数组
- 12. 分隔数组
1. 把数组中的 0 移到末尾
283. Move Zeroes (Easy)
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)
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)
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)
[
[ 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))
matrix = [
[ 1, 5, 9],
[10, 11, 13],
[12, 13, 15]
],
k = 8,
return 13.
��题参考:[Share my thoughts and Clean Java Code
二分查找解法:
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)
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)
要求不能修改数组,也不能使用额外的空间。
二分查找解法:
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)
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)
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)
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)
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)
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;
}
};