leetcode——数组和矩阵 第十、十一天 2/3

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)在这里插入图片描述

思路:不让动数组,只能原地排序,小于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

8 数组相邻差值的个数 (667)

9 数组的度 (697)

10 对角元素相等的矩阵 (766)

11 嵌套数组(565)

12 分割数组 (769)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值