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目录

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

相关文章推荐

二叉树前序、中序、后序遍历非递归写法的透彻解析

前言 在前两篇文章二叉树和二叉搜索树中已经涉及到了二叉树的三种遍历。递归写法,只要理解思想,几行代码。可是非递归写法却很不容易。这里特地总结下,透彻解析它们的非递归写法。其中,中序遍历的非递归写法最...

二叉树前序,中序,后序遍历详解

只要是搞计算机的,对数据结构中二叉树遍历都不陌生,但是如果用到的机会不多那么就会慢慢淡忘,温故而之新才是最好的学习方式,现在就重新温习一下这方面的知识。 首先我想先改变这几个遍历的名字(前根序遍历,...

精选:深入理解 Docker 内部原理及网络配置

网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。

什么是死锁,简述死锁发生的四个必要条件,如何避免与预防死锁

什么是死锁死锁是指多个进程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程都将无法向前推进。例如,在某一个计算机系统中只有一台打印机和一台输入 设备,进程P1正占用输入设备,同时又提出使...
  • jhonz
  • jhonz
  • 2016-10-11 11:09
  • 4785

数据结构(六)——二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现

一、基本概念 每个结点最多有两棵子树,左子树和右子树,次序不可以颠倒。 性质: 1、非空二叉树的第n层上至多有2^(n-1)个元素。 2、深度为h的二叉树至多有2^h-1个结点。 满二叉树:所有...

【算法】对一个20GB大的文件排序

设想你有一个20GB的文件,每行一个字符串,说明如何对这个文件进行排序。 内存肯定没有20GB大,所以不可能采用传统排序法。但是可以将文件分成许多块,每块xMB,针对每个快各自进行排序,存回文件系统...

Dota2 AI开发(一)环境配置

最近打Dota2,发现人机对战电脑AI,特别的傻。过了30分钟,友军又不带线,又不打野,来来回来闲逛;敌军5人抱团满图抓我。这种1V5经常以被控到死收场,真是伤感。忽然想起V社似乎开放了AI接口,身为...

二叉搜索树

定义 二叉搜索树(Binary Search Tree)或称二叉查找树,也称二叉排序树(Binary Sort Tree)。它或者是一棵空树,或者是具有下列性质的二叉树: 若左子树不空,则左子树上所有...

( 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...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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