自用算法笔记---死背

56.合并区间

在这里插入图片描述

class Solution {
public:
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        int N=intervals.size();
        vector<vector<int>> res;
        sort(intervals.begin(),intervals.end());//先按前端点排序,套路
        int l=intervals[0][0],r=intervals[0][1];
        vector<int> temp;//装每一个子区间的数组
        int i;
        temp.push_back(l);
        for(i=0;i<N;i++){
            if(intervals[i][0]<=r){//只要比之前有边界小都可并进来并更新右边界
                r=max(r,intervals[i][1]);
            }else{
                temp.push_back(r);//把之前收集的最大右边界装好
                res.push_back(temp);//
                l=intervals[i][0];//重新以遍历到的区间为起点
                r=intervals[i][1];
                temp=vector<int>();
                temp.push_back(l);
            }
        }
        if(i==N){//结束加上结尾
            temp.push_back(r);
            res.push_back(temp);
        }
        return res;
    }
};

61.旋转链表

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* rotateRight(ListNode* head, int k) {
        ListNode* t0=head;
        if(head==NULL) return NULL;
        ListNode* r;
        int n=0;
        for(auto i=head;i!=NULL;i=i->next){
            n++;//算共有几个节点
            if(i!=NULL&&i->next==NULL) r=i;//顺便找到旋转前的尾节点
        }
        int k0=k%n;//旋转几个点
        int cnt=0;
        ListNode* i;
        for(i=head;cnt+1!=n-k0;i=i->next){
            cnt++;//主要是找到旋转后的尾节点
        }
        r->next=head;//屁股连头
        ListNode* res=i->next;//旋转后的头
        i->next=NULL;//旋转后的尾断尾
        return res;
    }
};

AC.1451单链表快速排序

在这里插入图片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* getTail(ListNode* head) {
        while(head->next){
            head=head->next;
        }
        return head;
    }

    ListNode* quickSortList(ListNode* head) {
        if(!head||head->next==NULL) return head;
        auto left=new ListNode(-1),mid=new ListNode(-1),right=new ListNode(-1);//哨兵节点
        auto ltail=left,mtail=mid,rtail=right;//虚拟尾节点
        int val=head->val;
        for(auto i=head;i!=NULL;i=i->next){//以头节点val为标准进行划分,由此可生成三条链表
            if(i->val<val){
                ltail->next=i;
                ltail=ltail->next;
            }
            else if(i->val==val){
                mtail->next=i;
                mtail=mtail->next;
            }else{
                rtail->next=i;
                rtail=rtail->next;
            }
        }
        ltail->next=mtail->next=rtail->next=NULL;//结束符
        left->next=quickSortList(left->next);//左边的链表排序
        right->next=quickSortList(right->next);//右边的连接排序
        getTail(left)->next=mid->next;//左边对接中间
        getTail(left)->next=right->next;//中间对接右边,因为left和mid合成一段了,又因为mid可能为空所以用left表示中间段
        return left->next;//返回真正头节点
    }
};

AC.756蛇形矩阵

在这里插入图片描述

#include<iostream>
using namespace std;
const int N = 110;
int n, m;
int q[N][N];

int main() {
	scanf("%d%d", &n, &m);
	int dx[4] = { 0,1,0,-1 }, dy[4] = { 1,0,-1,0 };
	int x = 0, y = 0,d=0;
	for (int i = 1; i <= n*m; i++) {
		q[x][y] = i;
		int a = x + dx[d], b = y + dy[d];
		if (a < 0 || a >= n || b < 0 || b >= m || q[a][b]) {//||是只要有一个条件满足就重新寻找方向
			d = (d + 1) % 4;
			a = x + dx[d], b = y + dy[d];
		}
		x = a, y=b;将找到的方向赋给x,y
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			printf("%d ", q[i][j]);
		}
		puts("");
	}

}

73.矩阵置零

在这里插入图片描述
在这里插入图片描述

class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        int N=matrix.size();
        int M=matrix[0].size();
        int st1=0,st2=0;//用于判断第0行和第0列是否需要设0
        for(int i=0;i<N;i++){
            if(matrix[i][0]==0){
                st1=1;
                break;
            }
        }
        for(int i=0;i<M;i++){
            if(matrix[0][i]==0){
                st2=1;
                break;
            }
        }
        for(int i=1;i<N;i++){
            for(int j=1;j<M;j++){//从[1][1]开始找一旦有0则记录在对应行
            //和对应列的头部也就是第0行和第0列
                if(matrix[i][j]==0){
                    matrix[i][0]=0;
                    matrix[0][j]=0;
                }
            }
        }
        for(int i=1;i<N;i++){
            if(matrix[i][0]==0){
                for(int j=0;j<M;j++){
                    matrix[i][j]=0;
                }
            }
        }
        for(int i=1;i<M;i++){
            if(matrix[0][i]==0){
                for(int j=0;j<N;j++){
                    matrix[j][i]=0;//i是列噢
                }
            }
        }
        if(st1){//最后才处理第0行和第0列,因为前面拿来装东西了,脏了,所以留最后更新
            for(int i=0;i<N;i++){
                matrix[i][0]=0;
            }
        } 
        if(st2){
            for(int i=0;i<M;i++){
                matrix[0][i]=0;
            }
        }  
    }
};

AC.1452寻找矩阵的极小值

在这里插入图片描述

// Forward declaration of queryAPI.
// int query(int x, int y);
// return int means matrix[x][y].

class Solution {
public:
    vector<int> getMinimumValue(int n) {
        typedef long long LL;//因为是比小,有可能爆int
        int l=0,r=n-1,mid;
        while(l<r){//二分按列进行划分查找,直到找到最后一列
            mid=(l+r)>>1;
            LL val=INT_MAX,res;
            for(int i=0;i<n;i++){//在当前列上找到最小值
                LL val1=query(i,mid);
                if(val1<val){
                    val=val1;
                    res=i;
                }
            }
            int n1=query(res,mid-1);//减少api调用次数
            int n2=query(res,mid+1);
            if((mid>0&&n1>val&&mid<n&&n2>val)||
            (mid==0&&mid<n&&n2>val)||(mid>0&&n1>val&&mid==n-1)){
                return {res,mid};//在左边界和右边界和中间值的极小值情况
            }else if(n2<val){
                l=mid+1;//肯定在mid列的右边列区域
            }else{
                r=mid-1;//左边区域查找
            }
        }
        LL val=INT_MAX,res;
        for(int i=0;i<n;i++){//最后一列上进行查找返回极值
            LL val1=query(i,r);
            if(val1<val){
                val=val1;
                res=i;
            }
        }
        return {res,r};
    }
};

74.搜索二维矩阵

在这里插入图片描述
在这里插入图片描述

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int m=matrix.size(),n=matrix[0].size();
        int l=0,r=m-1;//先在行头二分查找
        while(l<r){
            int mid=(l+r)/2;
            if(matrix[mid][0]<target){
                l=mid+1;
            }else{
                r=mid;//结果会是第一个大于等于目标值的行头
            }
        }
        if(matrix[r][0]==target) return true;
        else if(matrix[r][0]<target){//行头小过目标值说明在当前行
            int l1=0,r1=n-1;
            while(l1<r1){
                int mid=(l1+r1)/2;
                if(matrix[r][mid]<target){
                    l1=mid+1;
                }else{
                    r1=mid;
                }
            }
            if(matrix[r][r1]==target) return true;
            else return false;
        }
        else{//行头大过目标值说明在上一行
            if(r==0) return false;//特殊情况
            int l1=0,r1=n-1;
            while(l1<r1){
                int mid=(l1+r1)/2;
                if(matrix[r-1][mid]<target){
                    l1=mid+1;
                }else{
                    r1=mid;
                }
            }
            if(matrix[r-1][r1]==target) return true;
            else return false;
        }
    }
};

75.颜色分类

在这里插入图片描述
在这里插入图片描述

class Solution {
public:
    void sortColors(vector<int>& nums) {//双指针
        int N=nums.size();
        int cnt0=0,cnt2=N-1;
        for(int i=0;i<N;i++){
            if(nums[i]==0&&i<cnt0){//如果是之前换过来的0就不用判断了
            }else if(i>cnt2){//判断到了2也不用判断了
                break;
            }
            else if(nums[i]==0){//只用排0和2,剩下就是1的位置了
                swap(nums[i],nums[cnt0]);
                cnt0++;
                if(nums[i]!=1) i--;//如果换过来的不是1还得回退重新判断
            }else if(nums[i]==2){
                swap(nums[i],nums[cnt2]);
                cnt2--;
                if(nums[i]!=1) i--;
            }
        }
    }
};

79.单词搜索

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

class Solution {
public:
    int st[7][7];//避免回走
    int res=0;//结果
    int N,M,L;
    bool exist(vector<vector<char>>& board, string word) {
        memset(st,0,sizeof 0);
        N=board.size(),M=board[0].size(),L=word.size();
        for(int i=0;i<N;i++){
            for(int j=0;j<M;j++){
                if(board[i][j]==word[0]){//起点对了就开始dfs
                    dfs(board,i,j,word,0);
                    if(res==1) return true;
                }
            }
        }
        return res==1;
    }
    void dfs(vector<vector<char>>& board,int x,int y,string& word
    ,int idx){
        if(x<0||y<0||x>=N||y>=M||st[x][y]||word[idx]!=board[x][y]) return;//越界或者回走或者不符
        else{
            if(idx==word.size()-1){//找到,结束
                res=1;
                st[x][y]=1;
                return;
            }
            st[x][y]=1;
        }
        dfs(board,x,y-1,word,idx+1);//四个方向走一下看看
        dfs(board,x-1,y,word,idx+1);
        dfs(board,x+1,y,word,idx+1);
        dfs(board,x,y+1,word,idx+1);
        st[x][y]=0;//恢复现场
    }
};

80.删除有序数组中的重复项Ⅱ

在这里插入图片描述
在这里插入图片描述

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int N=nums.size();
        int idx=1;//结果集是下标,原地装,因为结果集元素数必定比原来少或相等
        int cnt=1;//当前数字有几个了
        if(N<=2) return N;
        for(int i=1;i<N;i++){
            if(nums[i]!=nums[idx-1])//和前面不同就清0
                cnt=0;
            if(cnt<2){//装进结果集
                nums[idx++]=nums[i];
                cnt++;
            }
        }
        return idx;
    }
};

81.搜索旋转排序数组Ⅱ

在这里插入图片描述
在这里插入图片描述

class Solution {
public:
    bool search(vector<int>& nums, int target) {
        int n = nums.size();
        if (!n) {
            return false;
        }
        if (n == 1) {
            return nums[0] == target;
        }
        int l = 0, r = n - 1;
        while (l <= r) {
            int mid = (l + r+1) / 2;
            if (nums[mid] == target) return true;
            if(nums[mid]==nums[l]&&nums[mid]==nums[r]){//三都相同无法判断哪边有序,
            //且这仨必定不是目标值,所以一步步减少区间
                l++,r--;
            }else if (nums[l] <= nums[mid]) {//左边有序
                if (nums[l] <= target && target <= nums[mid]) {//目标值在左
                    r = mid - 1;
                } else {//在右
                    l = mid;
                }
            } else {//右
                if (nums[mid] <= target && target <= nums[r]) {
                    l = mid;
                } else {
                    r = mid - 1;
                }
            }
        }
        return false;
    }
};

82.删除排序链表中的重复元素Ⅱ

在这里插入图片描述
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        ListNode* pre=new ListNode(-1);//哨兵节点,其与now之间隔了一个节点哈
        if(head==NULL) return NULL;
        ListNode* now=head->next;
        pre->next=head;
        while(now!=NULL){
            if(now->val==pre->next->val){//now的值和前面相邻的值相同
                do{
                    now=now->next;
                }while(now!=NULL&&now->val==pre->next->val);//找到不同的为止
                if(pre->next==head) head=now;//头节点被删的话要改head
                pre->next=now;//删重复的节点
                if(now) now=now->next;//now往下走,要和pre之间隔一个格子的距离哈
            }else{
                pre=pre->next;
                now=now->next;
            }
        }
        return head;
    }
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值