数据结构
链表
从尾到头打印链表
题目
1 2 3 4 5 6 7
| 输入一个链表的头节点,按链表从尾到头的顺序返回每个节点的值(用数组返回)。
如输入{1,2,3}的链表如下图:
返回一个数组为[3,2,1]
0 <= 链表长度 <= 10000
|

解答
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
class Solution { public: vector<int> printListFromTailToHead(ListNode* head) { vector<int> result; while(head) { result.push_back(head->val); head = head->next; } reverse(result.begin(), result.end()); return result; } };
|
反转链表
题目
给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表头。
数据范围: 0\leq n\leq10000≤n≤1000
要求:空间复杂度 O(1)O(1) ,时间复杂度 O(n)O(n) 。
如当输入链表{1,2,3}时,
经反转后,原链表变为{3,2,1},所以对应的输出为{3,2,1}。
以上转换过程如下图所示:
解答
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
class Solution { public: ListNode* ReverseList(ListNode* pHead) { ListNode *pre = nullptr; ListNode *cur = pHead; ListNode *nex = nullptr; while (cur) { nex = cur->next; cur->next = pre; pre = cur; cur = nex; } return pre; } };
|
合并两个排序的链表
题目
输入两个递增的链表,单个链表的长度为n,合并这两个链表并使新链表中的节点仍然是递增排序的。
数据范围: 0 \le n \le 10000≤n≤1000,-1000 \le 节点值 \le 1000−1000≤节点值≤1000
要求:空间复杂度 O(1)O(1),时间复杂度 O(n)O(n)
如输入{1,3,5},{2,4,6}时,合并后的链表为{1,2,3,4,5,6},所以对应的输出为{1,2,3,4,5,6}
解答
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
|
class Solution { public: ListNode* Merge(ListNode* pHead1, ListNode* pHead2) { ListNode * pre = new ListNode(-1); ListNode * cur = pre; while(pHead1 && pHead2) { if(pHead1->val < pHead2->val) { cur->next = pHead1; pHead1 = pHead1->next; } else { cur->next = pHead2; pHead2 = pHead2->next; } cur = cur->next; } if(!pHead1) cur->next = pHead2; if(!pHead2) cur->next = pHead1; return pre->next; } };
|
两个链表的第一个公共结点
题目
输入两个无环的单向链表,找出它们的第一个公共结点,如果没有公共节点则返回空。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
数据范围: n \le 1000n≤1000
要求:空间复杂度 O(1)O(1),时间复杂度 O(n)O(n)
例如,输入{1,2,3},{4,5},{6,7}时,两个无环的单向链表的结构如下图所示:

输入分为是3段,第一段是第一个链表的非公共部分,第二段是第二个链表的非公共部分,第三段是第一个链表和二个链表的公共部分。 后台会将这3个参数组装为两个链表,并将这两个链表对应的头节点传入到函数FindFirstCommonNode里面,用户得到的输入只有pHead1和pHead2
解答
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
class Solution { public: ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) { ListNode *ta = pHead1; ListNode *tb = pHead2; while (ta != tb) { ta = ta ? ta->next : pHead2; tb = tb ? tb->next : pHead1; } return ta; } };
|
链表中环的入口结点
题目
给一个长度为n链表,若其中包含环,请找出该链表的环的入口结点,否则,返回null。
数据范围: n\le10000n≤10000,1<=结点值<=100001<=结点值<=10000
要求:空间复杂度 O(1)O(1),时间复杂度 O(n)O(n)
例如,输入{1,2},{3,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
|
class Solution { public: ListNode* EntryNodeOfLoop(ListNode* pHead) { ListNode *fast = pHead; ListNode *slow = pHead; while(fast && fast->next) { fast = fast->next->next; slow = slow->next; if(fast == slow) break; } if(!fast || !fast->next) return nullptr; fast = pHead; while(fast != slow) { fast = fast->next; slow = slow->next; } return fast; } };
|
链表中倒数最后k个结点
题目
输入一个长度为 n 的链表,设链表中的元素的值为 ai ,返回该链表中倒数第k个节点。
如果该链表长度小于k,请返回一个长度为 0 的链表。
数据范围:0 \leq n \leq 10^50≤n≤105,0 \leq a_i \leq 10^90≤a**i≤109,0 \leq k \leq 10^90≤k≤109
要求:空间复杂度 O(n)O(n),时间复杂度 O(n)O(n)
进阶:空间复杂度 O(1)O(1),时间复杂度 O(n)O(n)
例如输入{1,2,3,4,5},2时,对应的链表结构如下图所示:

其中蓝色部分为该链表的最后2个结点,所以返回倒数第2个结点(也即结点值为4的结点)即可,系统会打印后面所有的节点来比较。
解答
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
|
class Solution { public:
ListNode* FindKthToTail(ListNode* pHead, int k) { ListNode* r = pHead; while (k-- && r) r = r->next; if (k >= 0) return nullptr; ListNode* l = pHead; while (r) r = r->next, l = l->next; return l; } };
|
删除链表中重复的节点
题目
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表 1->2->3->3->4->4->5 处理后为 1->2->5
数据范围:链表长度满足 0 \le n \le 1000 \0≤n≤1000 ,链表中的值满足 1 \le val \le 1000 \1≤val≤1000
进阶:空间复杂度 O(n)*O*(n) ,时间复杂度 O(n) *O*(n)
例如输入{1,2,3,3,4,4,5}时,对应的输出为{1,2,5},对应的输入输出链表如下图所示:

例如
- 输入:
{1,2,3,3,4,4,5}
,输出:{1,2,5}
- 输入:
{1,1,1,8}
,输出:{8}
解答
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
|
class Solution { public: ListNode* deleteDuplication(ListNode* pHead) { if (!pHead) return NULL; ListNode* slow = new ListNode(-1), *fast = new ListNode(-1), *dummy = new ListNode(-1); dummy->next = pHead; slow = dummy; fast = dummy->next; while (fast) { while (fast->next && fast->val == fast->next->val) { fast = fast->next; } if (slow->next != fast) { slow->next = fast->next; fast = slow->next; } else { fast = fast->next; slow = slow->next; } } return dummy->next; } };
|
参考链接
- https://www.nowcoder.com/ta/coding-interviews