输入一个链表,按链表值从尾到头的顺序返回一个ArrayList
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {} };
ListNode* reverseListII(ListNode* head) { ListNode *L = (ListNode*)malloc(sizeof(ListNode)); L->next = NULL; ListNode *s; while (head) { s = (ListNode*)malloc(sizeof(ListNode)); s->val = head->val; s->next = L->next; L->next = s; head = head->next; } return L->next; }
ListNode* reverseListII_CPP(ListNode* head) { ListNode *L = new ListNode(-1); ListNode *s; while (head) { s = new ListNode(head->val); s->next = L->next; L->next = s; head = head->next; } return L->next; }
ListNode* reverseList(ListNode* head) { stack<int> stk; while (head) { stk.push(head->val); head = head->next; } ListNode *L = (ListNode*)malloc(sizeof(ListNode)); L->next = NULL; ListNode *r, *s; r = L; while (!stk.empty()) { s = (ListNode*)malloc(sizeof(ListNode)); s->val = stk.top(); stk.pop(); s->next = NULL; r->next = s; r = s; } r->next = NULL; return L->next; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
ListNode* removeNthFromEnd(ListNode* head, int n) { ListNode *fast = head, *slow = head; for (int i = 0; i < n; i++) { fast = fast->next; } if (fast == NULL) { return head->next; } while (fast->next) { fast = fast->next; slow = slow->next; } slow->next = slow->next->next; return head; }
|
给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。
示例 1:
输入: 1->1->2
输出: 1->2
示例 2:
输入: 1->1->2->3->3
输出: 1->2->3
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
ListNode* deleteDuplicates(ListNode* head) { ListNode *cur = head; while (cur && cur->next) { if (cur->val == cur->next->val) { cur->next = cur->next->next; } else { cur = cur->next; } } return head; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
ListNode* deleteDuplicatesII(ListNode* head) { if (!head || !head->next) return head; head->next = deleteDuplicates(head->next); return (head->val == head->next->val) ? head->next : head; }
|
deleteDuplicatesII-删除链表中重复元素II
给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。
示例 1:
输入: 1->2->3->3->4->4->5
输出: 1->2->5
示例 2:
输入: 1->1->1->2->3
输出: 2->3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
ListNode* deleteDuplicatesII(ListNode* head) { if (head == NULL || head->next == NULL) return head; ListNode *head_pre = new ListNode(-1); head_pre->next = head; ListNode *pre = head_pre, *cur = head, *last = NULL; while (cur && cur->next) { last = cur->next; if (cur->val == last->val) { while (last && cur->val == last->val) { last = last->next; } pre->next = last; cur = last; } else { pre = cur; cur = last; } } return head_pre->next; }
|
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例:
给定 1->2->3->4, 你应该返回 2->1->4->3.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
ListNode* swapPairs(ListNode* head) { ListNode *header = new ListNode(-1), *pre = header; header->next = head; while (pre->next && pre->next->next) { ListNode *t = pre->next->next; pre->next->next = t->next; t->next = pre->next; pre->next = t; pre = t->next; } return header->next; }
ListNode* swapPairs(ListNode* head) { if (!head || !head->next) return head; ListNode *t = head->next; head->next = swapPairs(head->next->next); t->next = head; return t; }
|
给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链表。k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序。
示例 :
给定这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
说明 :
你的算法只能使用常数的额外空间。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
|
ListNode* reverseKGroup(ListNode* head, int k) { if (!head || k == 1) return head; ListNode *header = new ListNode(-1), *pre = header, *cur = head; header->next = head; for (int i = 1; cur; ++i) { if (i % k == 0) { pre = reverseOneGrop(pre, cur->next); cur = pre->next; } else { cur = cur->next; } } return header->next; }
ListNode *reverseOneGrop(ListNode *pre, ListNode *next) { ListNode *last = pre->next, *cur = last->next; while (cur != next) { last->next = cur->next; cur->next = pre->next; pre->next = cur; cur = last->next; } return last; }
|
反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。
说明:
1 ≤ m ≤ n ≤ 链表长度。
示例:
输入: 1->2->3->4->5->NULL, m = 2, n = 4
输出: 1->4->3->2->5->NULL
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
ListNode* reverseBetween(ListNode* head, int m, int n) { ListNode *header = new ListNode(-1), *pre = header; header->next = head; for (int i = 0; i < m - 1; ++i) pre = pre->next; ListNode *cur = pre->next; for (int i = m; i < n; ++i) { ListNode *t = cur->next; cur->next = t->next; t->next = pre->next; pre->next = t; } return header->next; }
|
给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。
示例 1:
输入: 1->2->3->4->5->NULL, k = 2
输出: 4->5->1->2->3->NULL
解释:
向右旋转 1 步: 5->1->2->3->4->NULL
向右旋转 2 步: 4->5->1->2->3->NULL
示例 2:
输入: 0->1->2->NULL, k = 4
输出: 2->0->1->NULL
解释:
向右旋转 1 步: 2->0->1->NULL
向右旋转 2 步: 1->2->0->NULL
向右旋转 3 步: 0->1->2->NULL
向右旋转 4 步: 2->0->1->NULL
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
|
ListNode* rotateRight(ListNode* head, int k) { if (!head) return NULL; int n = 0; ListNode *cur = head; while (cur) { n++; cur = cur->next; } k %= n; ListNode *fast = head, *slow = head; for (int i = 0; i < k; ++i) { if (fast) fast = fast->next; } if (!fast) return head; while (fast->next) { fast = fast->next; slow = slow->next; } fast->next = head; fast = slow->next; slow->next = NULL; return fast; }
ListNode* rotateRight(ListNode* head, int k) { if (!head) return NULL; int n = 1; ListNode *cur = head; while (cur->next) { ++n; cur = cur->next; } cur->next = head; int stride = n - k % n; for (int i = 0; i < stride; ++i) { cur = cur->next; } ListNode *new_head = cur->next; cur->next = NULL; return new_head; }
|
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
|
bool isPalindrome(ListNode* head) { if (!head || !head->next) return true; stack<int> stk; ListNode *fast = head, *slow = head; stk.push(head->val); while (fast->next && fast->next->next) { fast = fast->next->next; slow = slow->next; stk.push(slow->val); } if (fast->next == NULL) { stk.pop(); } slow = slow->next; while (!stk.empty()) { if (stk.top() == slow->val) { slow = slow->next; stk.pop(); } else { return false; } } return true; }
bool isPalindromeII(ListNode* head) { if (!head || !head->next) return true; ListNode *fast = head, *slow = head; while (fast->next && fast->next->next) { fast = fast->next->next; slow = slow->next; } ListNode *cur = slow->next, *pre = head; while (cur->next) { ListNode *t = cur->next; cur->next = t->next; t->next = slow->next; slow->next = t; } slow = slow->next; while (slow) { if (slow->val == pre->val) { slow = slow->next; pre = pre->next; } else { return false; } } return true; }
|
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
|
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { ListNode *C, *s, *r; C = new ListNode(-1); r = C; while (l1 && l2) { if (l1->val <= l2->val) { s = new ListNode(l1->val); r->next = s; r = s; l1 = l1->next; } else { s = new ListNode(l2->val); r->next = s; r = s; l2 = l2->next; } } while (l1) { s = new ListNode(l1->val); r->next = s; r = s; l1 = l1->next; } while (l2) { s = new ListNode(l2->val); r->next = s; r = s; l2 = l2->next; } return C->next; }
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { if (l1 == NULL) return l2; if (l2 == NULL) return l1; ListNode *C = NULL; if (l1->val <= l2->val) { C = l1; C->next = mergeTwoLists(l1->next, l2); } else { C = l2; C->next = mergeTwoLists(l1, l2->next); } return C; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
ListNode* mergeKLists(vector<ListNode*>& lists) { if (lists.empty()) return NULL; int n = lists.size(); while (n > 1) { int k = (n + 1) / 2; for (int i = 0; i < n / 2; i++) { lists[i] = mergeTwoLists(lists[i], lists[i + k]); } n = k; } return lists[0]; }
ListNode *mergeTwoLists(ListNode* A, ListNode *B) { ListNode *C = new ListNode(-1); ListNode *p = C; while (A && B) { if (A->val < B->val) { p->next = A; p = A; A = A->next; } else { p->next = B; p = B; B = B->next; } } if (A) p->next = A; if (B) p->next = B; return C->next; }
ListNode* mergeKLists(vector<ListNode*>& lists) { auto cmp = [](ListNode*& a, ListNode*& b) { return a->val > b->val; }; priority_queue<ListNode*, vector<ListNode*>, decltype(cmp) > q(cmp); for (auto node : lists) { if (node) q.push(node); } ListNode *dummy = new ListNode(-1), *cur = dummy; while (!q.empty()) { auto t = q.top(); q.pop(); cur->next = t; cur = cur->next; if (cur->next) q.push(cur->next); } return dummy->next; }
|
给定一个链表,判断链表是否有环
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
bool hasCycle(ListNode *head) { if (!head || head->next == NULL) return false; ListNode *fast = head, *slow = head; while (fast && fast->next) { fast = fast->next->next; slow = slow->next; if (fast == slow) return true; } return false; }
|
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
ListNode *detectCycle(ListNode *head) { ListNode *fast = head, *slow = head; while (fast && fast->next) { fast = fast->next->next; slow = slow->next; if (slow == fast) break; } if (!fast || !fast->next) return NULL; slow = head; while (fast != slow) { fast = fast->next; slow = slow->next; } return slow; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
|
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { int lenA = 0, lenB = 0, lenDis; ListNode *p, *pLong, *pShort; p = headA; while (p) { lenA++; p = p->next; } p = headB; while (p) { lenB++; p = p->next; } lenDis = lenA - lenB; pLong = headA; pShort = headB; if (lenDis < 0) { pLong = headB; pShort = headA; lenDis = -lenDis; } for (int i = 0; i < lenDis; i++) { pLong = pLong->next; } while (pShort != pLong) { pLong = pLong->next; pShort = pShort->next; if (!pLong || !pShort) return NULL; } return pShort; }
|
给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。
你应当保留两个分区中每个节点的初始相对位置。
示例:
输入: head = 1->4->3->2->5->2, x = 3
输出: 1->2->2->4->3->5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
|
ListNode* partition(ListNode* head, int x) { ListNode *header = new ListNode(-1); header->next = head; ListNode *pre = header, *cur = head; while (pre->next && pre->next->val < x) { pre = pre->next; } cur = pre; while (cur->next) { if (cur->next->val < x) { ListNode *t = cur->next; cur->next = t->next; t->next = pre->next; pre->next = t; pre = pre->next; } else { cur = cur->next; } } return header->next; }
ListNode* partition(ListNode* head, int x) { if (head == NULL) return head; ListNode *header_A = new ListNode(-1); ListNode *header_B = new ListNode(-1); header_A->next = head; ListNode *cur = header_A, *p = header_B; while (cur->next) { if (cur->next->val < x) { p->next = cur->next; p = p->next; cur->next = cur->next->next; p->next = NULL; } else { cur = cur->next; } } p->next = header_A->next; return header_B->next; }
|