leetcode刷题 笔记

目录

206.反转链表


1.unordered_set

unordered_set 是 C++ 标准库中提供的一种集合容器,它是基于哈希表实现的,可以快速地插入、删除和查找元素。unordered_set 中的元素是无序的,不像 set 那样是有序的。

以下是一些关于 unordered_set 的重要特点和用法:

1.无序性:unordered_set 中的元素是无序的,插入顺序和元素值之间没有关联。

2.快速查找:由于 unordered_set 是基于哈希表实现的,查找元素的时间复杂度为 O(1),平均情况下是常数时间。

3.插入和删除:插入和删除元素的时间复杂度也是 O(1)。

4.不允许重复元素:unordered_set 中不允许存在重复的元素,每个元素在集合中只能出现一次。

5.迭代器:可以使用迭代器遍历 unordered_set 中的元素,但是迭代器不保证元素的顺序。

6.头文件:要使用 unordered_set,需要包含 <unordered_set> 头文件。

7.哈希表的count和find函数

2. lower_bound函数

auto it = lower_bound(row.begin(), row.end(), target);

lower_bound 函数来在一个容器中查找第一个不小于目标值的元素

并返回一个迭代器指向该位置。

3.两层for循环来查找 可以使用哈希表来优化

206.反转链表

解释:

/**
 * 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) {}
 *     //solution  2这个构造函数就是尾插法直接利用
 * };
 */

解法1:

//solution  1
        if(head==NULL ||head->next==NULL)return head;
        //没有节点和一个节点不需要反转
        //因为三个指针要避免野指针,所以<2节点就会出现野指针 
        //所以必须要提前返回
         ListNode*pA,*pB,*pC;
         pA=head,pB=head->next,pC=pB->next;
         //处理边界
         pA->next=NULL;
        while(pC){
        //反转
          pB->next=pA;
        //指针移动
          pA=pB;
          pB=pC;
          pC=pC->next;
          }
        //处理边界
        pB->next=pA;
        head=pB;
         return head;

解法2:

//solution  2
        ListNode *ans = NULL;
        for (ListNode *x = head; x != NULL; x = x->next) {
            ans = new ListNode(x->val,ans);//利用了其构造函数
            //new 比三个指针移动快多了
        }
        return ans;

解法3:

//solution  3
        //递归少了一个指针 将前一个节点存储在栈里
        if(!head||!head->next){//递归找最后一个节点返回去
            return head;
        }
        ListNode*newHead=reverseList(head->next);//递归下去
        head->next->next=head;//递归不用担心找不到前面的节点
        head->next=NULL;
        return newHead;//返回时一直是最后一个节点

234.回文链表

链表:

/**
 * 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) {}
 * };
 */

解法1:

class Solution {
public:
    bool isPalindrome(ListNode* head) {
        if(!head){
            return true;
        }

        //先找到链表的中点 ->next 后一半的开始节点
          ListNode* first=findmid(head)->next;
        //翻转链表
         ListNode*headB=reverseListNode(first);
        //判断回文
        while(headB){
             if(head->val!=headB->val){
                return false;
             }
             headB=headB->next;
             head=head->next;
        }
        return true;
    }


ListNode*findmid(ListNode*head){
    //快慢指针 找中点
    ListNode*fast=head;
    ListNode*slow=head;
    //指针要避免野指针
    while(fast->next&&fast->next->next){
        //避免长度不够判断进去野指针
        //&&短路
        slow=slow->next;
        fast=fast->next->next;
    }
    return slow;
    }
ListNode*reverseListNode(ListNode*first){
        //利用构造函数实现尾插法
        ListNode*ans=NULL;
        ListNode*x=first;//不修改原指针指向
        while(x){
            ans=new ListNode(x->val,ans);
            x=x->next;
        }
        return ans;
        //指针的指向会在函数内部被修改
}
};

解法2:

class Solution {
    ListNode*firsthead;
public:
    bool isPalindrome(ListNode* head) {
        firsthead=head;
        return recursivelyCheck(head);//递归检查
    }
    
bool  recursivelyCheck(ListNode*head){
    if(head){
    if(!recursivelyCheck(head->next)){
        //向下递归
        //判断下层的结果,如果有假就会一直传递假
        return false;
    }
    if(firsthead->val!=head->val){
        return false;
    }
    //相等 firsthead指针向后移动
    firsthead=firsthead->next;
    }
    return true;
    //空指针的时候返回上一个节点 就是尾节点 
    //return true 执行判断

    //不同时空对立
    }
};

24. 两两交换链表中的节点

/**
 * 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* swapPairs(ListNode* head) {
            //退出条件 没有节点和只剩一个节点 不需要交换
            if(!head||!head->next){
               return head;
            }
            //递归就是模拟情况
            //考虑三条指针
            ListNode*newhead=head->next;
            head->next=swapPairs(newhead->next);//两个一交换
            newhead->next=head;
            return newhead;
        }
};
 ListNode*pre=new ListNode(-1,head);//创建一个头节点,统一处理
        head=pre;
        ListNode*cur=head->next;
        while(cur&&cur->next){//退出判断条件 
             ListNode*tmp=cur->next;
             
             head->next=tmp;
             cur->next=tmp->next;
             tmp->next=cur;

             head=cur;
             cur=head->next;
        }
        return pre->next;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值