Linked List in Leetcode

141. 环形链表

给定一个链表,判断链表中是否有环。

双指针方法
链表问题中的一个重要的方法叫双指针法。定义两个指针,一个叫慢指针,另一个叫快指针。通常慢指针每次向前移动一个节点,而快指针每次向前移动若干个节点。这个方法通常用于寻找链表中特定的位置。比如找到链表的中点,可以让快指针每次移动两个节点。这样当快指针到达链表末尾时,慢指针刚好在链表中间的位置。

160. 相交链表

编写一个程序,找到两个单链表相交的起始节点。

例如,下面的两个链表

A:          a1 → a2
                   ↘
                     c1 → c2 → c3
                   ↗            
B:     b1 → b2 → b3

在节点 c1 开始相交。

注意:

  • 如果两个链表没有交点,返回 null.
  • 在返回结果后,两个链表仍须保持原有的结构。
  • 可假定整个链表结构中没有循环。
  • 程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。

基本思想是先对其两个列表,然后逐个进行比较就可以了。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        if(headA==nullptr || headB==nullptr) return nullptr;
        int lenA = 0, lenB = 0;
        length(headA, lenA);
        length(headB, lenB);
        int diff = (lenA>lenB)?lenA-lenB:lenB-lenA;
        while(diff>0)
        {
            if(lenA>lenB)
                headA = headA->next;
            else
                headB = headB->next;
            --diff;
        }
        while(headA!=nullptr && headB!=nullptr)
        {
            if(headA->val == headB->val) return headA;
            headA = headA->next;
            headB = headB->next;
        }
        return nullptr;
    }
    
    void length(ListNode *head, int &len)
    {
        while(head!=nullptr) 
        {
            len++;
            head = head->next;
        }
    }
};
View Code

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

示例 1:

输入: 1->1->2
输出: 1->2

示例 2:

输入: 1->1->2->3->3
输出: 1->2->3
基本思想就是两个指针,一个指向第一个,一个指向第二个,如果相等就删除,如果不相等就后移动
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        if(head == nullptr || head->next==nullptr)
            return head;
            
        ListNode *first = head;
        ListNode *second = head->next;
        
        while(second != nullptr)
        {
            if(first->val == second->val)
            {
                first->next = second->next;
                second = second->next;
            }
            else
            {
                first = second;
                second = second->next;
            }
        }
        return head;
    }
};
View Code

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

给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。

示例 1:

输入: 1->2->3->3->4->4->5
输出: 1->2->5

示例 2:

输入: 1->1->1->2->3
输出: 2->3
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        if(head == nullptr || head->next==nullptr)
            return head;
            
        //用一个dummy节点来当做head的prev
        ListNode dummy(0);
        dummy.next = head;
        ListNode *prev = &dummy;
        ListNode *first = prev->next;
        ListNode *second = first->next;
        // 用来表明状态的变化,从不相等,变成了相等,然后在根据这个状态变化来针对性的进行修改
        bool flag = false;
        
        while(second != nullptr)
        {
            if(first->val == second->val)
            {
                first->next = second->next;
                second = second->next;
                flag = true;
            }
            else
            {
                if(flag)
                {
                    prev->next = second;
                    first = second;
                    second = second->next;
                    flag = false;
                    continue;
                    
                }
                prev = first;
                first = second;
                second = second->next;
            }
        }
       // 如果flag为真,表明最后一个也是重复的元素,需要单独考虑,因为这个时候已经退出循环了
        if(flag)
        {
            prev->next = nullptr;
        }
        return dummy.next;
    }
};      
View Code

猜你喜欢

转载自www.cnblogs.com/randyniu/p/9165389.html
今日推荐