找工作刷题LeetCode题库

一、哈希相关 q1
找工作刷题LeetCode题库_第1张图片
1、暴力法(1):

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
    vector<int> res;
    for(int i=0;i<nums.size();i++)
    {
        for(int j=i+1;j<nums.size();j++)
        {
          if(nums[i]+nums[j]==target)
          {
              res=vector<int>({i,j});//(1)注意这一行容器(应该是一个匿名容器类对象)写法!!!
              break;//(2)break跳出最近的一层循环!
          }
        }
        if(res.size()>0)//(3)做这个判断是i到最后一个时j就超了res为空!
        {
            //return res;//(4)尽量吧返回写在结尾否则报错(gcc编译器要求每个控制流最后都要有返回)
            break;
        }
    }
    return res;
  }
};

问题(4):找工作刷题LeetCode题库_第2张图片
暴力法(2):

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        int len = nums.size();
        for(int i = 0; i < len-1; i++)//注意(1)
        for(int j = i + 1; j < len; j++)//注意(1)
        {
            if(nums[i] + nums[j] == target)
            return {i,j};// (2)return {i, j} 是vector的列表初始化方法,相当于返回一个包含值为i和j的vector
        }        
       return {};//(3)不要忘了!
    }
};

2、哈希法

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {

        unordered_map<int,int> m;//(1)注意该容器用法,其内部是hash结构!
//unordered_map map----模板的前2个参数<键,值>
        for(int i = 0; i<nums.size(); i++)
            m[nums[i]] = i;         //(2)向map中添加元素
        
        for(int i = 0; i<nums.size(); i++)
        {
            if(m.find(target-nums[i]) != m.end() && m[target-nums[i]] != i)  //(3)如果m中存在对应的键值,且不为i(为i就相当于有一个元素自己加自己刚好等于目标值!不符题意---题中要求每个元素只能用一次!)
                return {i, m[target-nums[i]]};//(4)
        }
        return {};//(5)
    }
};

(1)unordered_map详细介绍:
https://blog.csdn.net/weixin_45697774/article/details/104382942?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159258068619724811803420%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=159258068619724811803420&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_click~default-1-104382942.pc_search_back_js&utm_term=unordered_map

二、链表操作 q2 q19 q61
找工作刷题LeetCode题库_第3张图片

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        int len1=1;//记录l1的长度
        int len2=1;//记录l2的长度
        ListNode* p=l1;
        ListNode* q=l2;
        while(p->next!=NULL)//获取l1的长度
        {
            len1++;
            p=p->next;
        }
        while(q->next!=NULL)//获取l2的长度
        {
            len2++;
            q=q->next;
        }
        if(len1>len2)//l1较长,在l2末尾补零
        {
            for(int i=1;i<=len1-len2;i++)
            {
                q->next=new ListNode(0);
                q=q->next;
            }
        }
        else//l2较长,在l1末尾补零
        {
            for(int i=1;i<=len2-len1;i++)
            {
                p->next=new ListNode(0);
                p=p->next;
            }
        }
        p=l1;//L1和L2是链表的起始地址!
        q=l2;
        bool count=false;//记录进位
        ListNode* l3=new ListNode(-1);//存放结果的链表(的头结点)//-1???????????
        ListNode* w=l3;//l3的移动指针
        int i=0;//记录相加结果
        while(p!=NULL&&q!=NULL)
        {
            i=count+p->val+q->val;//不要考虑头结点不存数据,就认为l1和l2头结点也存数据???
            w->next=new ListNode(i%10);//每次循环创建一个新的节点!(并把新节点由上个节点的next位引用)!
            count=i>=10?true:false;
            w=w->next;
            p=p->next;
            q=q->next;
        }
        if(count)//若最后还有进位
        {
            w->next=new ListNode(1);
            w=w->next;
        }
        return l3->next; 
        
    }
};

链表视频B站: https://www.bilibili.com/video/BV1kx411g7Tj?from=search&seid=166366673325984904

–q19----------------------------------------------------------------------------------
找工作刷题LeetCode题库_第4张图片

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        if(!head | !head -> next) return NULL;//(1)处理n是头或者尾的特殊情况----不理解!!!????尤其是位与运算符???
        ListNode * fast = head, *slow = head;
        for(int i = 0; i < n; i++){
            fast = fast -> next;
        }
        if(!fast){//(2)处理n是头或者尾的特殊情况----不理解!!!????
        return head -> next;    
        }   
        while(fast -> next){
            fast = fast -> next;
            slow = slow -> next;
        }
        slow -> next = slow -> next -> next;
        return head;
    }
};  

问题:双指针快慢指针
(1)(2)不理解!!???

P61旋转链表-------------------------------------------------------------------------------
找工作刷题LeetCode题库_第5张图片

class Solution {
public:
    ListNode* rotateRight(ListNode* head, int k) {
    if(head==NULL||k==0){//(1)处理特殊情况!!!//null是Java写法(java所有关键字小写)!
        return head;
    }
    ListNode* cursor=head;//cursor游标
    ListNode* tail=NULL;//尾指针
    int length=1;
    while(cursor->next!=NULL)//循环 得到总长度
    {
        cursor=cursor->next;
        length++;
    }
    int loop=length-(k%length);//得到循环的次数//(4)这个是重点!!!
    tail=cursor;//(2)注意指向尾结点
    cursor->next=head;//(3)改成循环链表
    cursor=head;//指向头结点
    for(int i=0;i<loop;i++){//开始循环
        cursor=cursor->next;
        tail=tail->next;
    }
    tail->next=NULL;//(3)改成单链表
    return cursor;//返回当前头  
    }
};

注释:注意(4)!!!
在这里插入图片描述
找工作刷题LeetCode题库_第6张图片

P138. 复制带随机指针的链表

找工作刷题LeetCode题库_第7张图片

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* next;
    Node* random;
    
    Node(int _val) {    //构造函数
        val = _val;
        next = NULL;
        random = NULL;
    }
};
*/

class Solution {
public:
    Node* copyRandomList(Node* head) {
    if (!head) return nullptr;
        //(1)将克隆结点放在原结点后面
        Node* node = head;
        // 1->2->3  ==>  1->1'->2->2'->3->3'
        while (node) { // 用next连接
            Node* clone = new Node(node->val, node->next, nullptr);//克隆节点
            Node* temp = node->next;//使用临时指针temp暂时保存源节点所存储的下个节点地址(因为下一步拼接克隆节点就改变了他的指向了)
            node->next = clone;//原节点的后面接上克隆节点
            node = temp;//指针向后移一位(即移到原链表第二个原节点处)
        }
        node = head;
        while (node) { // (2)连接random
            if (node->random) node->next->random = node->random->next;//node->next->random新克隆节点的随机指针;node->random->next原节点的随机指针指向
            node = node->next->next;//跳到新链表的第三个(也就是原链表的原第二个节点)
        }
        // (3)还原原始链表,即分离原链表和克隆链表
        node = head;
        Node* ret = head->next;
        while (node->next) { 
            Node* temp = node->next;
            node->next = node->next->next;//注意这个node是在新链表中(即原链表和克隆链表组成的链表)一个节点一个节点遍历的、这样第1357...次遍历把原链表节点连接还原,第2468...次遍历把克隆链表粘合在一起!所以一边下来新原链表都分开了且各自粘合。
            node = temp;
        }
        return ret;    
    }
};

解题思路: 由于要求深拷贝所以各项都要对应拷贝:
将克隆结点放在原结点后面 1->2->3 ==> 1->1’->2->2’->3->3’!
先直接拷贝节点类的int val和Node* next至于随机指针先值为空指针nullptr!
第二步根据原链表随机指针挨个拷贝给新链表随机指针random!
最后分离原链表和克隆链表!
关于(3)如图:
找工作刷题LeetCode题库_第8张图片

你可能感兴趣的:(力扣刷题)