LeetCode-Linked List

原创 2015年12月18日 19:45:03

Linked List

24 Swap Nodes in Pairs

Given a linked list, swap every two adjacent nodes and return its head.

For example,
Given 1->2->3->4, you should return the list as 2->1->4->3.

Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.

分析:
题目要求:两个一组逆置相邻节点。
这是链表逆置的变种(升级)。但做法依然是那样:以前是逆置n个,现在是逆置两个,只不过需要逆置多次而已。注意细节,看图:逆置p1和p2,pPre和pNext分别指向前驱和后继。
Swap Nodes in Pairs

参考:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* swapPairs(struct ListNode* head) {
    //空链表和单一节点链表,不作处理
    if(NULL == head || NULL == head->next) return head;
    struct ListNode *p1, *p2, *pPre, *pNext;
    p1 = head, p2 = head->next;
    //第一对节点,做特殊处理
    pNext = p2->next;
    p2->next = p1;
    p1->next = pNext;
    pPre = p1;
    head = p2;  //这一句是特殊处理的理由
    while(pNext)
    {
        p1 = pNext;
        p2 = p1->next;
        if(NULL == p2) break;
        pNext = p2->next;
        //以下两句代码:逆置相邻节点
        p2->next = p1;
        p1->next = pNext;
        pPre->next = p2;
        pPre = p1;
    }
    return head;
}

148 Sort List

Sort a linked list in O(n log n) time using constant space complexity.

分析:
题目要求:对单链表排序,时间复杂度是O(n log n),空间复杂度是O(1)。
我们可以先把元素取出,排序好后,再放回去,这是参考1中的做法。时间复杂度满足,空间复杂度不满足。
另外,借助归并排序的思想,我们有了参考2。需要注意的是,如何使用快慢指针找到链表的中间节点?这需要多加体会。
参考1:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
#include <algorithm>
class Solution {
public:
    ListNode* sortList(ListNode* head) {
        if(NULL == head || NULL == head->next){
            return head;
        }
        vector<int> vec;
        ListNode *p = head;
        while(p){
            vec.push_back(p->val);
            p = p->next;
        }
        sort(vec.begin(), vec.end());   //n*logn
        p = head;
        int i = 0;
        while(p){
            p->val = vec[i];
            i++;
            p = p->next;
        }
        return head;
    }
};

参考2:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* merge(struct ListNode *head1, struct ListNode *head2)
{
     if(NULL == head1) return head2;
     if(NULL == head2) return head1;
     struct ListNode *head = (struct ListNode*)malloc(sizeof(struct ListNode));
     struct ListNode *p = head;
     p->next = NULL;
     while(head1 && head2)
     {
         if(head1->val < head2->val)
         {
             p->next = head1;
             head1 = head1->next;
         }
         else
         {
             p->next = head2;
             head2 = head2->next;
         }
         p = p->next;
     }
     if(head1)
     {
         p->next = head1;
     }
     if(head2)
     {
         p->next = head2;
     }     
     struct ListNode *temp = head;
     head = head->next;
     free(temp);  //释放头节点
     return head;
}
struct ListNode* mergeSort(struct ListNode *head)
{
    if(NULL == head || NULL == head->next) return head;
    //使用快慢指针,寻找中间节点,从而链表一分为二
    struct ListNode *slow, *fast, *p;
    slow = fast = head;
    while(fast)
    {
        fast = fast->next;
        if(fast)
        {
            fast = fast->next;
            if(NULL == fast) break;
        }
        else break;
        slow = slow->next;
    }
    //此时slow即是中间节点
    p = slow->next;
    slow->next = NULL;
    struct ListNode *pLeft = mergeSort(head);
    struct ListNode *pRight = mergeSort(p);
    return merge(pLeft, pRight);
}
struct ListNode* sortList(struct ListNode* head) {
    if(NULL == head || NULL == head->next) return head;
    return mergeSort(head);
}

61 Rotate List

Given a list, rotate the list to the right by k places, where k is non-negative.

For example:
Given 1->2->3->4->5->NULL and k = 2,
return 4->5->1->2->3->NULL.

分析:
这是链表逆置的变种,把握基本操作,其它的就没什么好说的了。
参考:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* rotateRight(struct ListNode* head, int k) {
    if(NULL == head || NULL == head->next || 0 == k) return head;
    struct ListNode *p, *pEnd;
    p = pEnd = head;
    int n = 1;
    while(pEnd->next)
    {
        pEnd = pEnd->next;
        n++;
    }
    k %= n;  //规范k值
    k = n - k;
    k--;
    while(k)
    {
        p = p->next;
        k--;
    }
    pEnd->next = head;
    head = p->next;
    p->next = NULL;
    return head;
}

25 Reverse Nodes in k-Group

Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.

If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.

You may not alter the values in the nodes, only nodes itself may be changed.

Only constant memory is allowed.

For example,
Given this linked list: 1->2->3->4->5

For k = 2, you should return: 2->1->4->3->5

For k = 3, you should return: 3->2->1->4->5

分析:
这是24 Swap Nodes in Pairs的升级,如果不会,就先弄懂24题。
参考:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* reverseKGroup(struct ListNode* head, int k) {
    if(NULL == head || NULL == head->next || k < 2) return head;
    int i, n;
    n = 0;
    struct ListNode *p = head;
    while(p){
        n++;
        p = p->next;
    }
    struct ListNode *pPre, *pCur, *pNext;
    struct ListNode *pStart, *pEnd;
    pStart = head;
    if(n >= k){
        pPre = pStart, pCur = pStart->next;
        i = 1;
        while(i < k){
            pNext = pCur->next;
            pCur->next = pPre;
            pPre = pCur;
            pCur = pNext;
            i++;
        }
        pEnd = pStart;
        pEnd->next = pCur;
        head = pPre;
        n -= k;
    }
    while(n >= k){
        pStart = pCur;
        pPre = pStart, pCur = pStart->next;
        i = 1;
        while(i < k){
            pNext = pCur->next;
            pCur->next = pPre;
            pPre = pCur;
            pCur = pNext;                
            i++;
        }
        pEnd->next = pPre;
        pStart->next = pCur;
        pEnd = pStart;
        n -= k;
    }
    return head;
}

206 Reverse Linked List

Reverse a singly linked list.

分析:
逆置链表,这是基本操作,必须要会。详细分析参看:链表逆置
参考1:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* reverseList(struct ListNode* head) {
    if (NULL == head || NULL == head->next) return head;
    struct ListNode *pPre, *pCur, *pNext;
    pPre = head, pCur = head->next;
    while (pCur)
    {
        pNext = pCur->next;
        if (pPre == head) pPre->next = NULL;
        pCur->next = pPre;
        pPre = pCur;
        pCur = pNext;
    }
    head = pPre;
    return head;    
}

参考2:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *reverseList(struct ListNode *head)
{
    if (NULL == head || NULL == head->next) return head;
    struct ListNode *pPre, *pCur, *pNext;
    pPre = head, pCur = head->next;
    while (pCur)
    {
        pNext = pCur->next;
        pCur->next = pPre;
        pPre = pCur;
        pCur = pNext;
    }
    head->next = NULL;
    head = pPre;
    return head;
}

92 Reverse Linked List II

Reverse a linked list from position m to n. Do it in-place and in one-pass.

For example:
Given 1->2->3->4->5->NULL, m = 2 and n = 4,

return 1->4->3->2->5->NULL.

分析:
这是上一题206 Reverse Linked List的加码,只是略升级。
参考:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* reverseBetween(struct ListNode* head, int m, int n) {
    if(NULL == head || NULL == head->next || m <= 0 || m >= n){
        return head;
    }
    int len = 0;
    struct ListNode *p = head;
    while(p){
        len++;
        p = p->next;
    }
    if(n > len){
        return head;
    }
    struct ListNode *pPre, *pStart, *pCur, *pNext;
    int i = 1;
    pPre = NULL, pStart = head;
    while(i < m){
        i++;
        pPre = pStart;
        pStart = pStart->next;
    }
    p = pStart;
    pCur = p->next;
    while(i < n){
        pNext = pCur->next;
        pCur->next = p;
        p = pCur;
        pCur = pNext;
        i++;
    }
    if(NULL == pPre){
        head = p;
    }
    else{
        pPre->next = p;
    }
    pStart->next = pCur;
    return head;
}

143 Reorder List

Given a singly linked list L: L0→L1→…→Ln-1→Ln,
reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…

You must do this in-place without altering the nodes' values.

For example,
Given {1,2,3,4}, reorder it to {1,4,2,3}.

分析:
使用快慢指针,找到整个的链表中间节点,从此链表一分为二,最后前后两部分merge。
参考:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
void reorderList(struct ListNode* head) {
    //空链表、单个节点或双节点都不用处理
    if (NULL == head || NULL == head->next || NULL == head->next->next) return;
    //寻找中间节点
    struct ListNode *fast, *slow;
    struct ListNode *pCur, *pPre, *pNext;
    struct ListNode *p1, *p2, *p;
    int flag1, flag2, n;
    flag1 = 2, n = 1;
    fast = slow = head;
    while (fast)
    {
        fast = fast->next;
        if (fast)
        {
            fast = fast->next;
            if (NULL == fast)
            {
                flag2 = 2;   //偶数个节点
                break;
            }
        }
        else
        {
            flag2 = 1;   //奇数个节点
            break;
        }
        slow = slow->next;
        n++;
    }
    if (slow->next->next)
    {
        pPre = slow->next;
        pCur = pPre->next;
        while (pCur)
        {
            pNext = pCur->next;
            pCur->next = pPre;    //逆置
            if (pPre == slow->next) pPre->next = NULL;    //置空,作为新的链表结尾
            pPre = pCur;
            pCur = pNext;
        }
        slow->next = pPre;    //连接
    }
    //将前后两部分合并
    p = head, p1 = head->next, p2 = slow->next;
    while (n)
    {
        if ((flag2 == 1 && p == slow) || (flag2 == 2 && p->next == NULL)) break;
        if (flag1 == 1)
        {
            p->next = p1;
            p = p1;
            if (p1) p1 = p1->next;
            flag1 = 2;
        }
        else
        {
            p->next = p2;
            p = p2;
            if (p2) p2 = p2->next;
            flag1 = 1;
        }
    }
    p->next = NULL;
}

19 Remove Nth Node From End of List

Given a linked list, remove the nth node from the end of list and return its head.

For example,

   Given linked list: 1->2->3->4->5, and n = 2.

   After removing the second node from the end, the linked list becomes 1->2->3->5.
Note:
Given n will always be valid.
Try to do this in one pass.

分析:
删除节点,关键是找到待删除节点的前驱。
参考:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
    if(NULL == head || n <= 0){
        return head;
    }
    int len = 0;
    ListNode *p = head;
    while(p){
        len++;
        p = p->next;
    }
    if(n >= len){
        n = len;
    }
    if(n == len){
        head = head->next;
    }
    else{
        int i = 1;
        p = head;
        while(i < len - n){
            i++;
            p = p->next;
        }
        p->next = p->next->next;
    }
    return head;    
}

203 Remove Linked List Elements

Remove all elements from a linked list of integers that have value val.

Example
Given: 1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6, val = 6
Return: 1 --> 2 --> 3 --> 4 --> 5

参考:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* removeElements(struct ListNode* head, int val) {
    ListNode *p, *q;
    while(head && head->val == val){
        p = head;
        head = head->next;
        //delete p;
    }
    if(NULL == head || NULL == head->next){
        return head;
    }
    p = head;
    while(p){
        q = p->next;
        while(q && q->val == val){
        q = q->next;
        }
        p->next = q;
        p = q;
    }
    return head;    
}

83 Remove Duplicates from Sorted List

Given a sorted linked list, delete all duplicates such that each element appear only once.

For example,
Given 1->1->2, return 1->2.
Given 1->1->2->3->3, return 1->2->3.

分析:
注意链表是已经排好序的。
参考:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* deleteDuplicates(struct ListNode* head) {
    if(NULL == head || NULL == head->next){
        return head;
    }
    ListNode *p1, *p2;
    p1 = head;
    while(1){
        p2 = p1->next;
        while(p2 && p2->val == p1->val){
            p2 = p2->next;
        }
        p1->next = p2;
        p1 = p2;
        if(p2 == NULL){
            break;
        }
    }
    return head;    
}

82 Remove Duplicates from Sorted List II

Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list.

For example,
Given 1->2->3->3->4->4->5, return 1->2->5.
Given 1->1->1->2->3, return 2->3.

分析:
只要是重复的就删除,一个都不保留,它和83题有区别。
参考1:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* deleteDuplicates(struct ListNode* head) {
    if(NULL == head || NULL == head->next) return head;
    struct ListNode *p, *pCur, *pPre;
    int n, val;
    pPre = NULL;
    p = pCur = head;
    while(p)
    {
        val = p->val;
        n = 0;
        while(p && p->val == val)
        {
            p = p->next;
            n++;
        }
        if(1 == n)
        {
            pCur->val = val;
            pPre = pCur;
            pCur = pCur->next;
        }
    }
    if(NULL == pPre) head = NULL;
    else pPre->next = NULL;
    return head;
}

参考2:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
#include <map>
class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        if(NULL == head || NULL == head->next){
            return head;
        }
        map<int, int> m;
        ListNode *pPre, *pCur;
        pCur = head;
        while(pCur){
            auto ite = m.find(pCur->val);
            if(ite != m.end()){
                (ite->second)++;
            }
            else{
                m.insert(make_pair(pCur->val, 1));
            }
            pCur = pCur->next;
        }
        pPre = NULL, pCur = head;
        auto ite = m.begin();
        while(ite != m.end()){
            if(ite->second == 1){
                pCur->val = ite->first;
                pPre = pCur;
                pCur = pCur->next;
            }
            ++ite;
        }
        if(pPre == NULL){
            head = NULL;
        }
        else{
            pPre->next = NULL;
        }
        return head;
    }
};

86 Partition List

Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.

You should preserve the original relative order of the nodes in each of the two partitions.

For example,
Given 1->4->3->2->5->2 and x = 3,
return 1->2->2->4->3->5.

分析:
目前的解法可以解决问题,但不够好,期待更好的解法。
参考:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
#include <vector>
class Solution {
public:
    ListNode* partition(ListNode* head, int x) {
        if(NULL == head) return head;
        vector<int> vec;
        ListNode *p = head;
        while(p)
        {
            vec.push_back(p->val);
            p = p->next;
        }
        //先把小于x的数放进去
        p = head;
        for(int i = 0; i < vec.size(); i++)
        {
            if(vec[i] < x)
            {
                p->val = vec[i];
                p = p->next;
            }
        }
        //最后把不小于x的数放进去
        for(int i = 0; i < vec.size(); i++)
        {
            if(vec[i] >= x)
            {
                p->val = vec[i];
                p = p->next;
            }
        }        
        return head;
    }
};

234 Palindrome Linked List

Given a singly linked list, determine if it is a palindrome.

Follow up:
Could you do it in O(n) time and O(1) space?

分析:
在链表上的回文判断。参考1的代码可以实现判断,但OJ提示超时。参考2则是把数字取出,放入到数组中,回归到一般情况。参考3是借助STL中stack来实现。
参考1:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
bool isPalindrome(struct ListNode* head) {
    if(NULL == head || NULL == head->next) return true;
    int flag = 2;  //标记节点个数的奇偶性
    struct ListNode *fast, *slow;
    fast = slow = head;
    while(fast)
    {
        fast = fast->next;
        if (NULL == fast)
        {
            flag = 1;
            break;
        }
        else if (NULL == (fast = fast->next)) break;
        slow = slow->next;
    }
    //把slow后的节点逆置
    struct ListNode *pPre, *pCur, *pNext;
    pPre = slow, pCur = slow->next;
    while(pCur)
    {
        pNext = pCur->next;
        pCur->next = pPre;
        pPre = pCur;
        pCur = pNext;
    }
    struct ListNode *p1, *p2;
    p1 = head, p2 = pPre;
    while(p1 != slow)
    {
        if(p1->val != p2->val) return false;
        p1 = p1->next;
        p2 = p2->next;
    }
    if(2 == flag) return p1->val == p2->val;
    return true;
}

参考2:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
 #include <vector>
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        if(NULL == head || NULL == head->next){
            return true;
        }
        vector<int> vec;
        ListNode *p = head;
        while(p){
            vec.push_back(p->val);
            p = p->next;
        }
        int size = vec.size();
        for(int i = 0; i <= size / 2; i++){
            if(vec[i] != vec[size - 1 - i]){
                return false;
            }
        }
        return true;
    }
};

参考3:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
#include <stack>
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        if(NULL == head || NULL == head->next) return true;
        int flag = 2;
        stack<int> stack_int;
        struct ListNode *fast, *slow;
        fast = slow = head;
        while(fast)
        {
            stack_int.push(slow->val);
            fast = fast->next;
            if(fast)
            {
                fast = fast->next;
                if(NULL == fast) break;
            }
            else {
                flag = 1;
                break;
            }
            slow = slow->next;
        }
        if(1 == flag) stack_int.pop();
        struct ListNode *p = slow->next;
        while(p)
        {
            if(p->val != stack_int.top()) return false;
            p = p->next;
            stack_int.pop();
        }
        return true;
    }
};

21 Merge Two Sorted Lists

Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.

分析:
归并两个有序链表。详细分析:有序链表的合并去重
参考:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {
    if(NULL == l1){
        return l2;
    }
    if(NULL == l2){
        return l1;
    }
    struct ListNode *head, *p1, *p2, *p;
    int flag = 0;
    p1 = l1, p2 = l2;
    if(p1->val < p2->val){
        head = p1;
        p1 = p1->next;
        flag = 1;
    }
    else{
        head = p2;
        p2 = p2->next;
        flag = 2;
    }
    p = head;
    while(p1 && p2){
        if(flag == 1){
            while(p1 && (p1->val <= p2->val)){
                p1 = p1->next;
                p = p->next;
            }
            if(!p1 || !p2){
                break;
            }
            p->next = p2;
            p2 = p2->next;
            p = p->next;
            flag = 2;
        }
        else{
            while(p2 && (p2->val <= p1->val)){
                p2 = p2->next;
                p = p->next;
            }
            if(!p1 || !p2){
                break;
            }
            p->next = p1;
            p1 = p1->next;
            p = p->next;
            flag = 1;            
        }
    }
    if(p1){
        p->next = p1;
    }
    if(p2){
        p->next = p2;
    }
    return head;    
}

23 Merge k Sorted Lists

141 Linked List Cycle

Given a linked list, determine if it has a cycle in it.

Follow up:
Can you solve it without using extra space?

参考:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
bool hasCycle(struct ListNode *head) {
    if (NULL == head || NULL == head->next) {
        return false;
    }
    struct ListNode *p1, *p2;
    p1 = head, p2 = head->next;
    while (true) {
        if (NULL == p2) {
            false;
        }
        if (p1 == p2) {
            return true;
        }
        p1 = p1->next;
        if (NULL == p2->next) {
            return false;
        }
        else {
            p2 = p2->next;
            if (NULL == p2->next) {
                return false;
            }
            p2 = p2->next;
        }
    }    
}

142 Linked List Cycle II

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

Note: Do not modify the linked list.

Follow up:
Can you solve it without using extra space?

分析:
题目要求:寻找环开始的位置。
1.快指针每次走两步,慢指针每次只走一步。当快、慢指针相遇时,快指针走过的路程(用2s表示)是慢指针(用s表示)的两倍。
2.快指针比慢指针多走过的路程(多走的路程也是s)只能是环的整数倍。此时把快指针重新放置在链表的开始节点,且快慢指针步伐一致,即每次都是走一步。可以预测:两者再走s步,又会相遇在同一个节点。(原因:s = s)
3.另一个重要的条件:两者有一段路程是共同的。
以上三点足以得出结论:再次相遇时,一定相遇在环开始的位置。(画图理解)
参考:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 bool hasCycle(struct ListNode *head, struct ListNode **encounter)
 {
     if(NULL == head) return false;
     struct ListNode *fast, *slow;
     fast = slow = head;
     while(fast)
     {
         fast = fast->next;
         if(NULL == fast) return false;
         else fast = fast->next;
         slow = slow->next;
         if(fast == slow)
         {
             *encounter = fast;
             return true;
         }
     }
     return false;
 }
struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode *encounter = NULL;
    if(false == hasCycle(head, &encounter)) return NULL;
    struct ListNode *p = head;
    while(p != encounter)
    {
        p = p->next;
        encounter = encounter->next;
    }
    return p;
}

160 Intersection of Two Linked Lists

Write a program to find the node at which the intersection of two singly linked lists begins.


For example, the following two linked lists:

A:          a1 → a2
                   ↘
                     c1 → c2 → c3
                   ↗            
B:     b1 → b2 → b3
begin to intersect at node c1.

Notes:
If the two linked lists have no intersection at all, return null.
The linked lists must retain their original structure after the function returns.
You may assume there are no cycles anywhere in the entire linked structure.
Your code should preferably run in O(n) time and use only O(1) memory.

参考:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    if(NULL == headA || NULL == headB){
        return NULL;
    }
    int i, n1, n2;
    n1 = n2 = 1;
    struct ListNode *p1, *p2;
    p1 = headA, p2 = headB;
    while(p1->next){
        n1++;
        p1 = p1->next;
    }
    while(p2->next){
        n2++;
        p2 = p2->next;
    }
    if(p1 != p2){
        return NULL;
    }
    p1 = headA, p2 = headB;
    if(n1 >= n2){
        for(i = 0; i < n1 - n2; i++){
            p1 = p1->next;
        }
    }
    else{
        for(i = 0; i < n2 - n1; i++){
            p2 = p2->next;
        }        
    }
    while(p1 != p2){
        p1 = p1->next;
        p2 = p2->next;
    }
    return p1;
}

147 Insertion Sort List

Sort a linked list using insertion sort.

参考:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
void swap(int *a, int *b){
    int t = *a;
    *a = *b;
    *b = t;
}
struct ListNode* insertionSortList(struct ListNode* head) {
    if(NULL == head || NULL == head->next){
        return head;
    }
    int i, j, n = 0;
    struct ListNode *p = head;
    while(p){
        n++;
        p = p->next;
    }
    int *nums = (int*)malloc(sizeof(int)*n);
    p = head;
    i = 0;
    while(p){
        nums[i++] = p->val;
        p = p->next;
    }
    //insertion sort
    for(i = 1; i < n; i++){
        j = i;
        while(j && nums[j] < nums[j - 1]){
            swap(nums + j, nums + j - 1);
            j--;
        }
    }
    p = head;
    i = 0;
    while(p){
        p->val = nums[i];
        p = p->next;
        i++;
    }
    free(nums);
    return head;
}

237 Delete Node in a Linked List

Write a function to delete a node (except the tail) in a singly linked list, given only access to that node.

Supposed the linked list is 1 -> 2 -> 3 -> 4 and you are given the third node with value 3, the linked list should become 1 -> 2 -> 4 after calling your function.

参考:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    void deleteNode(ListNode* node) {
        if(node){
            ListNode *p1, *p2;
            p1 = node, p2 = node->next;
            while(p2->next){
                p1->val = p2->val;
                p1 = p2;
                p2 = p2->next;
            }
            p1->val = p2->val;
            delete p2;
            p1->next = NULL;
        }
    }
};

138 Copy List with Random Pointer

109 Convert Sorted List to Binary Search Tree

2 Add Two Numbers

You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8

参考:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
    if(NULL == l1) return l2;
    if(NULL == l2) return l1;
    struct ListNode *head = (struct ListNode*)malloc(sizeof(struct ListNode));
    struct ListNode *p1, *p2, *p;
    p1 = l1, p2 = l2, p = head;
    int more = 0;  //more表示进位值
    p->val = (p1->val + p2->val) % 10;
    more = (p1->val + p2->val) / 10;
    p1 = p1->next, p2 = p2->next;
    while(p1 && p2)
    {
        p->next = (struct ListNode*)malloc(sizeof(struct ListNode));
        p = p->next;
        p->val = (p1->val + p2->val + more) % 10;
        more = (p1->val + p2->val + more) / 10;    
        p1 = p1->next, p2 = p2->next;
    }
    while(p1)
    {
        p->next = (struct ListNode*)malloc(sizeof(struct ListNode));
        p = p->next;
        p->val = (p1->val + more) % 10;
        more = (p1->val + more) / 10;
        p1 = p1->next;
    }
    while(p2)
    {
        p->next = (struct ListNode*)malloc(sizeof(struct ListNode));
        p = p->next;
        p->val = (p2->val + more) % 10;
        more = (p2->val + more) / 10;
        p2 = p2->next;        
    }
    if(more)//仍有进位
    {
        p->next = (struct ListNode*)malloc(sizeof(struct ListNode));
        p = p->next;
        p->val = more;
    }
    p->next = NULL;
    return head;
}

所有代码下载:LeetCode-Linked List

期待更好的解法~

所有内容目录:CCPP Blog目录

版权声明:本文为博主原创文章,转载,请注明出处。若是商业用途,请事先联系作者。

相关文章推荐

CCPP Blog 目录

CCPP Blog 结构、算法、C、CPP 博客中的所有系列和专栏的目录都可在这里找到

娓娓道来c指针 (8)开发可变参数函数

在c语言中,可变参数的函数极其常见,如常用的printf()。可变参数函数的一般形式如下: 返回值类型 函数名(类型1 参数1,类型2 参数2,...类型n 参数n,...); 如上所示,这是一个典型...

LeetCode--Linked List.cpp

  • 2015年12月14日 22:22
  • 23KB
  • 下载

( Leetcode 92 ) Reverse Linked List II

题目:Reverse Linked List II Reverse a linked list from position m to n. Do it in-place and in one...

【LeetCode】Linked List Cycle II

参考链接 http://www.cnblogs.com/x1957/p/3406448.html 题目描述 Linked List Cycle II   Give...

【LeetCode】 Delete Node in a Linked List

Delete Node in a Linked List  Total Accepted: 1872 Total Submissions: 3662 Write a...

leetcode328. Odd Even Linked List

Given a singly linked list, group all odd nodes together followed by the even nodes. Please note her...

LeetCode Reverse Linked List II

题目 Reverse a linked list from position m to n. Do it in-place and in one-pass. For example: Giv...

leetcode:Linked List Cycle II

COPY FROM: 比I麻烦点的就是找到循环开始点TAT I只是判断是否循环。要求不使用额外空间(不然hash就可以了 按I的思路,我们又慢指针S和快指针F。。。F走两...

【LeetCode】Linked List Cycle II

题目 Given a linked list, return the node where the cycle begins. If there is no cycle, return nu...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:LeetCode-Linked List
举报原因:
原因补充:

(最多只允许输入30个字)