1 把数组中的0移到末尾
2 改变矩阵维度
3 找出数组中最长的连续1
4 有序矩阵查找
5 有序矩阵的 Kth Element★★
6 一个数组元素在[1,n]之间,其中一个数被替换为另一个数,找出重复的数和丢失的数
7 找出数组中重复的数,数组值在[1,n]之间
8 数组相邻差值的个数
9 数组的度
10 对角元素相等的矩阵
11 嵌套数组
12 分割数组
1 把数组中的0移到末尾(283)
思路:要非常注意数组越界的问题
i找0,j找非0,交换,注意每次遍历j的开始位置是max(i,j)
,j不需要每次都从i后一个开始
代码
//i找0,j找非0,交换,
class Solution {
public:
void swap(vector<int>&nums, int i, int j)
{
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
void moveZeroes(vector<int>& nums) {//注意它不需要返回值呀
int i = 0;
int j = 0;
int n = nums.size();
while(i < n && j < n)
{
if(i<n && nums[i] != 0)
{
++i;
}
//i的位置是0了,j是要在i后面的,但是一开是i会比j大;
j = max(i,j);
if(j<n && nums[j]==0)
{
++j;
// swap(nums, i,j);
}
if(i<n && j<n)
{
swap(nums, i,j);
}
}
}
};
2 改变矩阵维度(566)
代码
//新建一个目标大小的数组并开始遍历,对每个位置先转为拉直后的一维坐标,然后再算出原数组中的对应位置复制过来即可
class Solution {
public:
vector<vector<int>> matrixReshape(vector<vector<int>>& nums, int r, int c) {
int m = nums.size();
int n = nums[0].size();
if(m*n != r*c) return nums;
//vector<vector<int>>& res(m*n,0);//初始化方法错误!要初始化一个二维数组的呀
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];
}
}
return res;
}
};
3 找出数组中最长的连续1 (485)
代码: count++ 和++count 不如直接写count+1
class Solution {
public:
int findMaxConsecutiveOnes(vector<int>& nums) {
int count = 0;
int res = 0;
for(int num:nums)//遍历
{
count = (num == 0)?0:count+1;//不能写count++
res = max(res, count);
}
return res;
}
};
4 有序矩阵查找(240)
思路
左下角作为搜索的起始位置,因为从左下角往上减小往右增大
写代码时还是要注意边界问题,以及vector可以使用函数
代码
//把起始位置设在左下,这个数字往右变大,往上变小,例如找17,18比17小,就往上到10,比10大往右一路大到17
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
// if(matrix[].size() == 0 && …………)直接判是否为空就好了,因为是vector,可以函数
if(matrix.empty() || matrix[0].empty()) return false;
//先判断一下边界,毕竟是个有序数组
int m = matrix.size(); int n = matrix[0].size();
//if(target<matrix[0][0] || target>matrix.back().back()) return false;//好,但试试这个
if(target<matrix[0][0] || target> matrix[m-1][n-1]) return false;
//定义初始位置
int x = matrix.size()-1, y = 0;
while(true)//学习while(true) 要么找到返回true,要么到最后一个break的用法,
{
if(matrix[x][y]>target) x = x-1;
else if(matrix[x][y]<target) y = y+1;
else return true;//找到
if(x<0 || y>=n) break;
}
return false;
}
};
5 有序矩阵的 Kth Element(378)
有序数组分别行有序列有序(都是递增的),找出第k个最小元素
- 方法1:利用堆,使用一个最大堆,然后遍历数组每一个元素,将其加入堆中,根据最大堆的性质,大的元素会排到最前面,然后我们看当前堆中的元素个数是否大于k,大于的花就将首元素去掉,结束循环后堆首元素就是我们所求
- 方法2:二分查找:……8会
代码(要还原再重做的)
在优先队列(priority_queue)中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。优先队列具有最高级先出 (first in, largest out)的行为特征。
.emplace
() 原地构造一个元素并插入队列
……
嗯……8会,整理堆排序再来
6 一个数组元素在[1,n]之间,其中一个数被替换为另一个数,找出重复的数和丢失的数 (645)
思路:
用一个conut数组记录每个数字出现的次数,分别出现2次和0次的就是我们要找的,评论区还有更巧妙地方法,不想看了==
代码
//如果先排序再遍历那就时间复杂度嗯log就算了,如果两次遍历就是n
class Solution {
public:
vector<int> findErrorNums(vector<int>& nums) {
vector<int> res(2,0), cnt(nums.size(),0);//用cnt统计每个数字每次出现的次数
for(int num:nums) ++cnt[num-1];
for(int i = 0; i<cnt.size(); ++i)
{
if(res[0]!= 0 && res[1]!=0) return res;//已经找到了就不用再遍历了,可以返回结果了
if(cnt[i] == 2) res[0] = i+1;
if(cnt[i] == 0) res[1] = i+1;
}
return res;
}
};
7 找出数组中重复的数,数组值在[1,n]之间](287)![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/bcda6f7fcd6a059f4059f60c6b3b6f55.png)
思路:不让动数组,只能原地排序,小于O(n²)
只能用二分,在区间[1,n]中搜索,先求mid,然后遍历整个数组,统计小于等于mid的个数,如果个数小于等于mid,则在[mid,1]内,反之就在[1,mid]之间,然后依次类推,直到搜索完成
代码:与mid比较时<=、>= 中的等于不要忘记,看看东哥的二分笔记
class Solution {
public:
int findDuplicate(vector<int>& nums) {
int left = 1, right = nums.size();
while(left<right)//一共是right个数,放的是1~right-1的数字
{
int mid =left+(right-left)/2, cnt = 0;//左边位置+(右边位置-左边位置)
for(int num:nums)
{
if(num<=mid) cnt++;
}
if(cnt<=mid) left = mid+1;
else right = mid;
}
// return right;//没啥大问题
return left;
}
};
明天吧==, 欸今天爸爸和超超哥哥回家,从下午一点开始就在聊天各种聊天,还是超级开心的,九点半才开始回房间学习,刚刚写完一个C++so初级的笔记,就11点了,今天就当休息吧,明天任务重重(不知道明天上午还会不会聊天哈哈哈,但是超超下午就回去了爸爸估计也马上回去上班了,聚一聚聊聊天(大声聊聊天)还是非常开心的!明天继续早起做题整理笔记(加点点运动),先做题有时间再看笔记,理智思考还是要抓紧才行,还有很多不会很多要准备呀,cazaeryo