数据结构-数组与矩阵
- 有序矩阵查找240. Search a 2D Matrix II
- 有序矩阵的 Kth Element 378. Kth Smallest Element in a Sorted Matrix
- 找出数组中重复的数,数组值在 [1, n] 之间 287. Find the Duplicate Number(Medium)
- 数组相邻差值的个数 667. Beautiful Arrangement II
- 对角元素相等的矩阵 766. Toeplitz Matrix(Easy)
- 嵌套数组 565. Array Nesting(Medium)
- 分隔数组 769. Max Chunks To Make Sorted
数组与矩阵总结:
- 有序考虑二分,无序也可考虑二分,搜索的目标值可以是索引也可以是值
- 差分数组
有序矩阵查找
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int n = matrix.size();
if(n == 0)
return false;
int m = matrix[0].size();
int i = 0, j = m-1;
while(i < n && j >= 0){
if(matrix[i][j] == target)
return true;
else if(matrix[i][j] > target)
j -= 1;
else
i += 1;
}
return false;
}
};
有序矩阵的 Kth Element
和Merge k sorted list问题相似
typedef pair<int,int> P;
struct cmp
{
bool operator()(P a, P b){
return a.second > b.second; // 建小顶堆
}
};
class Solution {
public:
int kthSmallest(vector<vector<int>>& matrix, int k) {
int n = matrix.size(), m = matrix[0].size();
priority_queue<P, vector<P>, cmp> pq;
for(int i = 0;i < m; i++){ //处理第0行
pq.push(make_pair(i, matrix[0][i]));
}
vector<int> unused_row(m, 1); // 每一列未处理的行号
while(k > 1){
P p = pq.top();
pq.pop();
int col = p.first;
if(unused_row[col] < n){
pq.push(make_pair(col, matrix[unused_row[col]][col]));
unused_row[col] += 1;
}
k -= 1;
}
return pq.top().second;
}
};
找出数组中重复的数,数组值在 [1, n] 之间
class Solution {
public:
int findDuplicate(vector<int>& nums) {
// 暴力查找O(n^2)
// 排序后再找O(nlogn) 要改变原数组
// 二分查找O(nlogn) 不改变原数组
// 问题转换为循环链表找环 O(n)
int lo = 1, hi = nums.size() - 1;
while(lo < hi){
int mid = lo + (hi - lo) / 2;
int cnt = 0;
for(int i = 0;i < nums.size(); i++){
if(nums[i] <= mid)
cnt += 1;
}
if(cnt > mid)
hi = mid;
else
lo = mid + 1;
}
return lo;
}
};
数组相邻差值的个数
class Solution {
public:
vector<int> constructArray(int n, int k) {
// 举例法
// 假设n=9
// 不太好实现
// 当k = n-1 = 8时
// num 1 9 2 8 3 7 4 6 5
// dif 8 7 6 5 4 3 2 1
// 当k < n-1 k=5时
// num 1 9 2 8 3 4 5 6 7
// dif 8 7 6 5 1 1 1 1
// 从diff入手
// num 1 k+1 2 k-1 3 k-2...
// diff k k-1 k-2 k-3 ... 1
// num 1 6 2 5 3 4 7 8 9
// idff 5 4 3 2 1 3 1 1
vector<int> ans;
int lo = 1, hi = k+1;
while(lo <= hi){
ans.push_back(lo++);
if(lo <= hi)
ans.push_back(hi--);
}
for(int i = k+2;i <= n; i++)
ans.push_back(i);
return ans;
}
};
对角元素相等的矩阵
class Solution {
public:
bool check(vector<vector<int> >& matrix, int n, int m, int i, int j){
int maxi = i, maxj = j;
while(maxi+1 < n && maxj+1 < m){
maxi += 1;
maxj += 1;
}
while(i < maxi && j < maxj){
if(matrix[i][j] != matrix[maxi][maxj])
return false;
i += 1;
j += 1;
}
return true;
}
bool isToeplitzMatrix(vector<vector<int>>& matrix) {
int n = matrix.size(), m = matrix[0].size();
// 从左到右遍历对角线
for(int j = 0;j < m; j++){
if(!check(matrix, n, m, 0, j))
return false;
}
// 从上到下遍历对角线
for(int i = 1;i < n; i++){
if(!check(matrix, n, m, i, 0))
return false;
}
return true;
}
};
嵌套数组
class Solution {
public:
int arrayNesting(vector<int>& nums) {
int ans = 0;
for(int i = 0;i < nums.size(); i++){
int tmp = i;
int cnt = 0;
if(nums[i] != -1){
while(nums[tmp] != -1){
int t = nums[tmp];
nums[tmp] = -1;
tmp = t;
cnt += 1;
}
}
if(cnt > ans)
ans = cnt;
}
return ans;
}
};
分隔数组
class Solution {
public:
int maxChunksToSorted(vector<int>& arr) {
int i = 0, cnt = 0;
while(i < arr.size()){
int j = arr[i];
for(int k = i;k <= j; k++){
j = max(j, arr[k]);
}
i = j+1;
cnt += 1;
}
return cnt;
}
};