一刷leetcode——链表

92. Reverse Linked List II

题意:将链表中第m到第n个元素翻转

我的思路:指针数组

我的代码:

class Solution {
public:
    ListNode* reverseBetween(ListNode* head, int m, int n) {
        vector<ListNode*> tmp(n-m+1);
        ListNode* ans = new ListNode(0), *l;
        ListNode* ret= ans;
        ans->next = head;
        int i = 0;
        while (ans) {
            if (i == m-1) {
                l = ans;
                ans = ans->next;
                for (int j = 0; j < n-m+1; j++) {
                    tmp[j] = ans;
                    ans = ans->next;
                }
                for (int j = n-m; j >= 0; j--) {
                    l->next = tmp[j];
                    l = l->next;
                }
                l->next = ans;
                break;
            }
            ans = ans->next;
            i++;
        }
        return ret->next;
    }
};
View Code

206. Reverse Linked List

题意:将链表转置

我的思路:递归实现,1A

我的代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverse(ListNode* head) {
        ListNode* ret = head;
        if (head->next) {
            ret = reverse(head->next);
            head->next->next = head;
        } 
        return ret;
    }
    ListNode* reverseList(ListNode* head) {
        if (head == NULL) return head;
        ListNode* ans, *tmp = head;
        ans = reverse(head);
        tmp->next = NULL;
        return ans;
    }
};
View Code

九章最优解:循环实现,被秒成了渣T T

class Solution {
public:
    /**
     * @param head: The first node of linked list.
     * @return: The new head of reversed linked list.
     */
    ListNode *reverse(ListNode *head) {
        ListNode *prev = NULL;
        while (head != NULL) {
            ListNode *temp = head->next;
            head->next = prev;
            prev = head;
            head = temp;
        }
        return prev;
    }
};
View Code

128. Longest Consecutive Sequence

题意:给定一个数组,输出最长的连续数字长度,要求时间复杂度O(n)

我的思路:map记录都出现了什么数,然后搜每个数字上下共多少个数,查到的数都删除可以降低重复搜索

我的代码:

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        int ans = 0;
        map<int, int> m;
        for (int i = 0; i < nums.size(); i++) m[nums[i]] = 1;
        while (!m.empty()) {
            map<int, int>::iterator it = m.begin();
            int tmp = 1, val = it->first, i = 1;
            m.erase(it);
            while (m.find(val+i) != m.end()) {
                m.erase(m.find(val+i));
                i++;
                tmp++;
            }
            i = 1;
            while (m.find(val-i) != m.end()) {
                m.erase(m.find(val-i));
                i++;
                tmp++;
            }
            ans = max(tmp, ans);
        }
        return ans;
    }
};
View Code

133. Clone Graph

题意:复制一个无向图

我的思路:bfs加map

我的代码:

class Solution {
public:
    UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
        if (node == NULL) return NULL;
        queue<UndirectedGraphNode *> q;
        map<UndirectedGraphNode *, UndirectedGraphNode *> m;
        map<UndirectedGraphNode *, bool> flag;
        q.push(node);
        flag[node] = 1;
        while (!q.empty()) {
            int n = q.size();
            for (int i = 0; i < n; i++) {
                UndirectedGraphNode *tmp = q.front();
                q.pop();
                UndirectedGraphNode *hehe, *nei;
                if (m.find(tmp) == m.end()) {
                    hehe = new UndirectedGraphNode(tmp->label);
                    m[tmp] = hehe;
                } else 
                    hehe = m[tmp];
                for (int j = 0; j < tmp->neighbors.size(); j++) {
                    if (m.find(tmp->neighbors[j]) == m.end()) {
                        nei = new UndirectedGraphNode(tmp->neighbors[j]->label);
                        m[tmp->neighbors[j]] = nei;
                    } else 
                        nei = m[tmp->neighbors[j]];
                    hehe->neighbors.push_back(nei);
                    if (flag.find(tmp->neighbors[j]) == flag.end()) {
                        q.push(tmp->neighbors[j]);
                        flag[tmp->neighbors[j]] = 1;
                    }
                }
            }
        }
        return m[node];
    }
};
View Code

138. Copy List with Random Pointer

题意:创建一个链表的深拷贝,其中含有随机指针

我的思路:走三遍,第一遍把每个节点复制出来坠在后边,第二遍给复制出的节点的随机指针复制,第三遍将复制出的节点提出来并将原链表复原

我的代码:

class Solution {
public:
    RandomListNode *copyRandomList(RandomListNode *head) {
        RandomListNode *front = head;
        while (front) {
            RandomListNode *tmp= new RandomListNode(front->label);
            tmp->next = front->next;
            front->next = tmp;
            front = tmp->next;
        }
        front = head;
        while (front) {
            if (front->random) front->next->random = front->random->next;
            front = front->next->next;
        }
        RandomListNode *tmp = new RandomListNode(0);
        RandomListNode *ans = tmp;
        while (head) {
            tmp->next = head->next;
            tmp = tmp->next;
            head->next = head->next->next;
            head = head->next;
        }
        return ans->next;
    }
};
View Code

141. Linked List Cycle

题意:判断链表中是否有环

我的思路:两个指针一快(每次两步)一慢(每次一步),如果不会相遇,则无环

我的代码:

class Solution {
public:
    bool hasCycle(ListNode *head) {
        if (head == NULL) return 0;
        ListNode * fast = head, *slow = head;
        while (slow->next && fast->next && fast->next->next) {
            slow = slow->next;
            fast = fast->next->next;
            if (slow == fast) return 1;
        }
        return 0;
    }
};
View Code

九章最优解:一样

class Solution {
public:
    /**
     * @param head: The first node of linked list.
     * @return: True if it has a cycle, or false
     */
    bool hasCycle(ListNode *head) {
        // write your code here
        ListNode *fast,*slow;
        if(head==NULL) return false;
        slow=head;
        fast=head->next;
        while(fast!=NULL && fast->next!=NULL)
        {
            if(slow==fast) return true;
            slow=slow->next;
            fast=fast->next->next;
        }
        return false;
    }
};
View Code

142. Linked List Cycle II

题意:找到链表环的起点

我的思路:快慢指针,快的是慢的速度的两倍,两指针相遇时改为相同速度,则再次相遇时就是环的起点(画个图很容易理解)

我的代码:

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        if (head == NULL) return NULL;
        ListNode * fast = head, *slow = head;
        while (slow->next && fast->next && fast->next->next) {
            slow = slow->next;
            fast = fast->next->next;
            if (slow == fast) {
                slow = head;
                while (slow != fast) {
                    slow = slow->next;
                    fast = fast->next;
                }
                return slow;
            }
        }
        return NULL;
    }
};
View Code

143. Reorder List

题意:将链表 L0→L1→…→Ln-1→Ln,重排为 L0→LnL1→Ln-1→L2→Ln-2→…

我的思路:指针数组。。

我的代码:

class Solution {
public:
    void reorderList(ListNode* head) {
        vector<ListNode*> hehe;
        ListNode* tmp = head;
        while (tmp) {
            ListNode* gg = tmp;
            hehe.push_back(gg);
            tmp = tmp->next;
        }
        int n = hehe.size(), cnt = 0, i = 0;
        tmp = new ListNode(0);
        while (cnt < n) {
            tmp->next = hehe[i];
            tmp = tmp->next;
            cnt++;
            if (cnt < n) {
                tmp->next = hehe[n-1-i];
                tmp = tmp->next;
                cnt++;
            }
            i++;
        }
        tmp->next = NULL;
    }
};
View Code

soluton解法:快慢指针,慢指针指到一半,将后半段倒置再合并

class Solution {
public:
    void reorderList(ListNode* head) {
        if (head==nullptr || head->next==nullptr) return ;
        //Find mid of the link list
        ListNode *slow = head;
        ListNode *fast = head;   
        while( fast && fast->next) {
            slow = slow->next;
            fast = fast->next->next;
        }
        //break link list and reverse the second 
        ListNode* mid = slow->next;
        slow->next = nullptr;
        mid = reverseList(mid);
        //merge two link list
        mergeTwoLists(head, mid);
    }
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode* head = new ListNode(0);
        ListNode* dummy = head;        
        while(l1 && l2) {
            head->next = l1;
            head = head->next;
            l1=l1->next;
            head->next = l2;
            head = head->next;
            l2=l2->next;
        }
        head->next = l1 ? l1 : l2;
        return dummy->next;   
    }
    ListNode* reverseList(ListNode* head) {
        ListNode* prev = NULL;
        while (head) {
            ListNode* next = head->next;
            head->next = prev;
            prev = head;
            head = next;
        }
        return prev;
    }
};
View Code

147. Insertion Sort List

题意:链表的插入排序

我的思路:常规题,1A

我的代码:

class Solution {
public:
    ListNode* insertionSortList(ListNode* head) {
        if (head == NULL) return NULL;
        ListNode* ans = new ListNode(0);
        while (head) {
            ListNode* tmp = ans;
            while (tmp->next && tmp->next->val < head->val)
                tmp = tmp->next;
            ListNode* hehe = new ListNode(head->val);
            hehe->next = tmp->next;
            tmp->next = hehe;
            head = head->next;
        }
        return ans->next;
    }
};
View Code

148. Sort List

题意:链表归并排序

我的代码:

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode *res = new ListNode(0);
        ListNode *ans = res;
        while (l1 && l2) {
            if (l1->val <= l2->val) {
                res->next = l1;
                l1 = l1->next;
                res = res->next;
            } else {
                res->next = l2;
                l2 = l2->next;
                res = res->next;
            }
        }
        if (l1) res->next = l1;
        else
            res->next = l2;
        return ans->next;
    }
    ListNode* sortList(ListNode* head) {
        if (head == NULL || head->next == NULL) return head;
        ListNode* f = head->next->next, *s = head;
        while (f && f->next) {
            f = f->next->next;
            s = s->next;
        }
        ListNode* r = sortList(s->next);
        s->next = NULL;
        return mergeTwoLists(sortList(head), r);
    }
};
View Code

160. Intersection of Two Linked Lists

题意:两个链表会交汇成一条,求交汇的第一个结点,要求时间复杂度为O(n),空间复杂度为O(1)

我的思路:不会。。

solution解法:太妙!以麻花状遍历,两个指针分别从a、b走,a走完改道走b,另一个同理,他俩最多走两个链表长度必相遇(或者都是NULL)

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode *cur1 = headA, *cur2 = headB;
        while(cur1 != cur2){
            cur1 = cur1 ? cur1->next : headB;
            cur2 = cur2 ? cur2->next : headA;
        }
        return cur1;
    }
};
View Code

九章最优解:

class Solution {
public:
    /**
     * @param headA: the first list
     * @param headB: the second list
     * @return: a ListNode
     */
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        // write your code here
        if(headA == NULL || headB == NULL)
            return NULL;
        ListNode* iter1 = headA;
        ListNode* iter2 = headB;
        int len1 = 1;
        while(iter1->next != NULL)
        {
            iter1 = iter1->next;
            len1 ++;
        }
        int len2 = 1;
        while(iter2->next != NULL)
        {
            iter2 = iter2->next;
            len2 ++;
        }
        if(iter1 != iter2)
            return NULL;
        if(len1 > len2)
        {
            for(int i = 0; i < len1-len2; i ++)
                headA = headA->next;
        }
        else if(len2 > len1)
        {
            for(int i = 0; i < len2-len1; i ++)
                headB = headB->next;
        }
        while(headA != headB)
        {
            headA = headA->next;
            headB = headB->next;
        }
        return headA;
    }
};
View Code

173. Binary Search Tree Iterator

题意:完成操作每次输出排序二叉树中下一个最小的值

我的思路:栈

我的代码:

class BSTIterator {
public:
    TreeNode *gg;
    stack<TreeNode *> s;
    BSTIterator(TreeNode *root) {
        gg = root;
    }

    /** @return whether we have a next smallest number */
    bool hasNext() {
        return !(gg == NULL && s.empty());
    }

    /** @return the next smallest number */
    int next() {
        TreeNode *ans;
        if (gg == NULL) {
            ans = s.top();
            s.pop();
            gg = ans->right;
        } else {
            while (gg->left) {
                s.push(gg);
                gg = gg->left;
            }
            ans = gg;
            gg = ans->right;
        }
        return ans->val;
    }
};
View Code

203. Remove Linked List Elements

题意:去掉链表中的某个值

我的思路:常规题,写的不如人家好 

我的代码:

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        ListNode *ans = head;
        while (head && head->val == val) {
            ans = head->next;
            head = head->next;
        }
        while (head && head->next) {
            if (head->next->val == val) head->next = head->next->next;
            else head = head->next;
        }
        return ans;
    }
};
View Code

九章最优解:

class Solution {
public:
    /**
     * @param head a ListNode
     * @param val an integer
     * @return a ListNode
     */
    ListNode *removeElements(ListNode *head, int val) {
        ListNode dummy;
        dummy.next = head;
        head = &dummy;
        
        while (head->next != NULL) {
            if (head->next->val == val) {
                head->next = head->next->next;
            } else {
                head = head->next;
            }
        }
        
        return dummy.next;
    }
};
View Code

234. Palindrome Linked List

题意:判链表是否回文,要求时间O(n)

我的思路:栈存放前半部分

我的代码:

class Solution {
public:
    bool isPalindrome(ListNode* head) {
        if (head == NULL || head->next == NULL) return 1;
        stack<int> s;
        ListNode *fast = head, *slow = head;
        while (fast && fast->next) {
            s.push(slow->val);
            slow = slow->next;
            fast = fast->next->next;
        }
        if (fast) slow = slow->next;
        while (slow) {
            if (slow->val != s.top()) return 0;
            s.pop();
            slow = slow->next;
        }
        return 1;
    }
};
View Code

solution解法:递归,我服

class Solution {
public:
    ListNode* temp;
    bool isPalindrome(ListNode* head) {
        temp=head;
        return check(head);
    }
    bool check(ListNode* p)
    {
        if(!p) return true;
        bool ispal=check(p->next)&&(temp->val==p->val);
        temp=temp->next;
        return ispal;
    }
};
View Code

328. Odd Even Linked List

题意:将链表1、3、5……个节点放前边,2、4、6……个节点放后边形成一个新链表

我的思路:链表基本操作

我的代码:

class Solution {
public:
    ListNode* oddEvenList(ListNode* head) {
        if (head == NULL) return head;
        ListNode *odd = new ListNode(0), *even = new ListNode(0);
        ListNode* ret = odd, *tmp = even;
        while (head && head->next) {
            odd->next = head;
            even->next = head->next;
            head = head->next->next;
            odd = odd->next;
            even = even->next;
        }
        if (head) {
            odd->next = head;
            odd = odd->next;
        }
        even->next = NULL;
        odd->next = tmp->next;
        return ret->next;
    }
};
View Code

382. Linked List Random Node

题意:等概率输出链表的节点值

我的思路:蓄水池采样

我的代码:

class Solution {
public:
    ListNode* h;
    /** @param head The linked list's head.
        Note that the head is guaranteed to be not null, so it contains at least one node. */
    Solution(ListNode* head) {
        h = head;
    }
    
    /** Returns a random node's value. */
    int getRandom() {
        int n = 1, ans;
        ListNode* tmp = h;
        while (tmp) {
            if (rand()%n == 0) ans = tmp->val;
            n++;
            tmp = tmp->next;
        }
        return ans;
    }
};
View Code

 

posted @ 2017-03-30 16:13  Silence、  阅读(202)  评论(0编辑  收藏  举报