0
点赞
收藏
分享

微信扫一扫

力扣数据结构14天学习计划—day7

开源分享 2022-05-01 阅读 75

力扣141—环形链表

力扣141

相关标签哈希表、双指针、链表

题意

给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。

如果链表中存在环 ,则返回 true 。 否则,返回 false 。

解题思路—双指针+哈希

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution 
{
public:
    bool hasCycle(ListNode *head) 
    {
        // 法1、双指针
        /*
        ListNode* slow,* fast;
        fast=slow=head;
        // 判断条件是 fast!=nullptr&&fast->next!=nullptr
        // 因为,如果fast->next==NULL的话,fast指针走两步就会报错,即 NULL->next会报错
        // 如果fast->next为最后一个节点了(假设无环),fast走两步就会到达NULl
        //下一次判断循环条件时,fast为NULL就会跳出循环,从而返回false,表示无环。
        while(fast!=nullptr&&fast->next!=nullptr)
        {
            slow=slow->next;
            fast=fast->next->next;
            if(slow==fast)
                return true;
        }
        return false;
        */
        //法2、哈希表
        unordered_set<ListNode*> uset;
        ListNode* node=head;
        while(node!=NULL)
        {
            if(uset.count(node)>=1)
                return true;
            uset.insert(node);
            node=node->next;
        }
        return false;
    }
};

力扣21—合并两个有序链表

力扣21

 相关标签:递归、链表

题意

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。  

解法1—递归

如果 l1 或者 l2 一开始就是空链表 ,那么没有任何操作需要合并,所以我们只需要返回非空链表。否则,我们要判断 l1 和 l2 哪一个链表的头节点的值更小,然后递归地决定下一个添加到结果里的节点。如果两个链表有一个为空,递归结束。

递归解析:

  • 终止条件:当两个链表都为空时,表示我们对链表已合并完成。
  • 如何递归:我们判断 l1 和 l2 头结点哪个更小,然后较小结点的 next 指针指向其余结点的合并结果。(调用递归)

 

 

 

/**
 * 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* mergeTwoLists(ListNode* list1, ListNode* list2) 
    {

        //递归法
        if(list1==nullptr)
            return list2;
        if(list2==nullptr)
            return list1;
        if(list1->val <= list2->val)
        {
            list1->next = mergeTwoLists(list1->next,list2);
            return list1;
        }
        else
        {
            list2->next=mergeTwoLists(list1,list2->next);
            return list2;
        }
    }
};

 解法2—迭代

创建一个虚拟头结点,建立一个pre指针,指向结果链表中的最后一个节点。一次遍历 l1和l2两个链表,将较小节点插入到结果链表中,然后较小节点后移,pre也后移使其指向结果链表中最后一个节点。

/**
 * 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* mergeTwoLists(ListNode* list1, ListNode* list2) 
    {
        // 迭代法
        ListNode* node1=list1,*node2=list2;
        ListNode* dummyHead=new ListNode(-1);   //虚拟头结点,将最终返回的结果接在它之后
        ListNode* pre=dummyHead; //pre指向 结果链表 中最后一个节点
        
        while(node1&&node2)
        {
            if( node1->val <= node2->val ) //node1的值要小一点
            {
               //就讲node1插入到pre的后面
               pre->next=node1;
               //同时,node1和pre都要后移
               node1=node1->next;
               pre=pre->next;
            }
            else
            {
               pre->next=node2;
               node2=node2->next;
               pre=pre->next;
            }
        }
        if(node1)
            pre->next=node1;
        if(node2)
            pre->next=node2;
        ListNode* res = dummyHead->next;
        delete dummyHead;
        return res;
        
    }
};

力扣203—移除链表元素

力扣203

题意

 

解题思路—创建虚拟头结点和不创建虚拟头结点

/**
 * 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* removeElements(ListNode* head, int val) 
    {
        //法1,创建一个虚拟头结点
        /*
       ListNode* dummyHead = new ListNode(0,nullptr);
       dummyHead->next=head;
       ListNode* cur = dummyHead;
       while(cur->next!=nullptr)
       {
           if(cur->next->val==val)
           {
               ListNode* del_node = cur->next;
               cur->next=del_node->next;
               delete del_node;
           }
           else
           {
               cur=cur->next;
           }
       }
       head=dummyHead->next;
       delete dummyHead;
       return head;
       */

       //法2,不创建虚拟头结点,考虑首节点为删除节点的情况
       while(head!=NULL&&head->val==val)
       {
           head=head->next;
       }
       if(!head)
       {
           return NULL;
       }
       ListNode* cur = head;
       while(cur->next!=NULL)
       {
           if(cur->next->val==val)
           {
               cur->next=cur->next->next;
           }
           else
           {
               cur=cur->next;
           }
       }
       return head;
    }
};
举报

相关推荐

0 条评论