
算法刷题之链表
算法刷题之链表
本杰明玩编程
做过后端开发,Android Framework,App开发。熟悉编程语言C++,Java/Kotlin,python。现在主要做自然语言处理相关的研发工作,主要包括kws,asr,nlu,dm,tts。
展开
-
138. 复制带随机指针的链表
题目:给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。要求返回这个链表的 深拷贝。我们用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:val:一个表示 Node.val 的整数。random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为 null 。方法一:哈希表unordered_mapclass Solution {public:原创 2020-09-09 21:52:04 · 135 阅读 · 0 评论 -
23. 合并K个升序链表
题目:给你一个链表数组,每个链表都已经按升序排列。请你将所有链表合并到一个升序链表中,返回合并后的链表。方法一:归并+分治函数代码:class Solution {public: ListNode* mergeKLists(vector<ListNode*>& lists) { if(lists.size()==0) { return NULL; } return mergesor原创 2020-09-09 09:45:09 · 133 阅读 · 0 评论 -
147. 对链表进行插入排序
题目:对链表进行插入排序。题解思路:方法:穿针引线函数代码:class Solution {public: ListNode* insertionSortList(ListNode* head) { if(!head||!head->next) { return head; } ListNode *dummy=new ListNode(0); ListNode *p=dummy;原创 2020-09-05 15:38:55 · 87 阅读 · 0 评论 -
86. 分隔链表
题目:给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。你应当保留两个分区中每个节点的初始相对位置。题解思路:方法:双指针就行分割遍历链表,把小于x的链表L1进行串起来,大于x的链表L2串起来,最后L1的下一个结点就是L2的头结点。函数代码:class Solution {public: ListNode* partition(ListNode* head, int x) { ListNode *dummy1=ne原创 2020-09-05 15:38:28 · 140 阅读 · 0 评论 -
143. 重排链表
题目:给定一个单链表 L:L0→L1→…→Ln-1→Ln ,将其重新排列后变为: L0→Ln→L1→Ln-1→L2→Ln-2→…你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。方法:双指针+快慢指针+翻转链表1.快慢指针找到切分链表2.翻转右半部分链表3左右合并拼接,依次合并函数代码:class Solution {public: void reorderList(ListNode* head) { if(!head||!head->next原创 2020-09-05 15:38:07 · 135 阅读 · 0 评论 -
445. 两数相加 II
题目:给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。你可以假设除了数字 0 之外,这两个数字都不会以零开头。进阶:如果输入链表不能修改该如何处理?换句话说,你不能对列表中的节点进行翻转。题解思路:方法:栈函数代码一:class Solution {public: ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { stack&原创 2020-09-05 15:37:32 · 85 阅读 · 0 评论 -
234. 回文链表
题目:请判断一个链表是否为回文链表。题解思路:方法一:暴力法遍历链表,将链表里元素的值放入数组里面,然后再判断数组里面的数字是不是回文数字。函数代码一:class Solution {public: bool isPalindrome(ListNode* head) { if(!head) { return true;; } ListNode *p=head; int len=0;原创 2020-09-05 15:37:10 · 97 阅读 · 0 评论 -
剑指 Offer 06. 从尾到头打印链表
题目:输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。题解思路:方法一:satck+vector+双遍历遍历链表,将链表的元素的值放入栈中,再将栈中的元素放入数组中。注意:这里stack存的是链表元素的值。 stack< int >s;函数代码:class Solution {public: vector<int> reversePrint(ListNode* head) { vector<int>res;原创 2020-09-04 14:28:17 · 116 阅读 · 0 评论 -
剑指 Offer 52. 两个链表的第一个公共节点
方法一:暴力法+求长度法(不推荐)函数代码:class Solution {public: ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { ListNode *p=headA; int len1=0; ListNode *q=headB; int len2=0; int dis=0; while(p)原创 2020-09-04 14:08:22 · 197 阅读 · 0 评论 -
142. 环形链表 II(找出链表环的起始点)
题目:给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。说明:不允许修改给定的链表。题解思路:方法:双指针函数代码:class Solution {public: ListNode *detectCycle(ListNode *head) { if(!head||!head->next)原创 2020-09-04 11:41:46 · 168 阅读 · 0 评论 -
141. 环形链表
题目:给定一个链表,判断链表中是否有环。为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。题解思路:方法一:双指针+快慢指针+判断是否相遇函数代码:class Solution {public: bool hasCycle(ListNode *head) { if(!head||!head->next) { return fals原创 2020-09-04 11:27:38 · 93 阅读 · 0 评论 -
61. 旋转链表
题目:给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。题解思路:方法一:链表头尾相接+巧用环1.遍历链表获得长度len。可能k会大于len,所以要进行取余处理。2.遍历到链表末尾结点时,将链表头尾相接,串起来。在遍历到len-k%len个结点时,断开。下一个结点就是旋转链表的头结点了。函数代码:class Solution {public: ListNode* rotateRight(ListNode* head, int k) {原创 2020-09-04 11:15:32 · 127 阅读 · 0 评论 -
92. 反转链表 II(翻转部分链表)
题目:反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。说明:1 ≤ m ≤ n ≤ 链表长度。方法:双指针+穿针引线函数代码:class Solution {public: ListNode* reverseBetween(ListNode* head, int m, int n) { if(!head) { return head; } ListNode *dummy=new ListN原创 2020-09-04 10:39:46 · 138 阅读 · 0 评论 -
24. 两两交换链表中的节点
题目:给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。题解思路:方法:穿针引线+四个指针函数代码:class Solution {public: ListNode* swapPairs(ListNode* head) { ListNode *dummy=new ListNode(0); dummy->next=head; ListNode *p=dummy;原创 2020-09-04 01:08:31 · 133 阅读 · 0 评论 -
19. 删除链表的倒数第N个节点
题目:给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。题解:方法一:一次遍历+双指针函数代码:class Solution {public: ListNode* removeNthFromEnd(ListNode* head, int n) { if(!head) { return head; } ListNode *p=new ListNode(0); p-&g原创 2020-09-04 00:35:47 · 96 阅读 · 0 评论 -
237. 删除链表中的节点
题目:请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点。传入函数的唯一参数为 要被删除的节点 。函数代码:class Solution {public: void deleteNode(ListNode* node) { node->val=node->next->val; ListNode *t=node->next; node->next=t->next; }};..原创 2020-09-04 00:21:46 · 85 阅读 · 0 评论 -
148. 排序链表
题目:在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。方法:归并排序+双指针+fast+slow最佳代码:class Solution {public: ListNode* sortList(ListNode* head) { if(!head||!head->next) { return head; } ListNode *fast=head; Li原创 2020-09-04 00:21:22 · 140 阅读 · 0 评论 -
2. 两数相加
题目:给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。您可以假设除了数字 0 之外,这两个数都不会以 0 开头。题解思路:方法:while(l1||l2),循环判断对于sum分别对l1和l2进行求和,carry进位标志为bool,不对carry进行sum/10;函数代码:class Solution {public: ListNo原创 2020-09-03 13:29:03 · 152 阅读 · 0 评论 -
328. 奇偶链表
题目:给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。请尝试使用原地算法完成。你的算法的空间复杂度应为 O(1),时间复杂度应为 O(nodes),nodes 为节点总数。题解思路:方法:穿针引线引入一个r结点保存第一个偶数结点,待奇数结点指向结束就指向r结点。函数代码:class Solution {public: ListNode* oddEvenList(ListNode* head) {原创 2020-09-03 11:22:37 · 114 阅读 · 0 评论 -
82. 删除排序链表中的重复元素 II
题目:给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。题解思路:方法:引入pre指针,穿针引线函数代码:class Solution {public: ListNode* deleteDuplicates(ListNode* head) { if(!head) { return head; } int flag=0; ListNode *cur=原创 2020-09-03 10:56:57 · 92 阅读 · 0 评论 -
83. 删除排序链表中的重复元素
题目:给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。注意:链表已经排序,排序,排序无排序是另外一种解法;方法:引入pre指针+next指针。穿针引线法函数代码:class Solution {public: ListNode* deleteDuplicates(ListNode* head) { if(!head||!head->next) { return head; }原创 2020-09-03 10:19:38 · 157 阅读 · 0 评论 -
剑指 Offer 24. 反转链表&力扣206
题目:定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。方法一:迭代翻转+就地翻转+指针后移函数代码:class Solution {public: ListNode* reverseList(ListNode* head) { if(!head) { return NULL; } ListNode *pre=NULL; ListNode *cur=head;原创 2020-09-03 08:22:54 · 151 阅读 · 0 评论 -
203. 移除链表元素
题目:删除链表中等于给定值 val 的所有节点。方法一:引入虚拟头结点dummy函数代码:class Solution {public: ListNode* removeElements(ListNode* head, int val) { if(!head) { return 0; } ListNode *dummy=new ListNode(0); dummy->next=he原创 2020-09-03 01:07:51 · 82 阅读 · 0 评论 -
8.30搜狐笔试
题目:给定一个单向链表(长度未知),请设计一个既节省时间又节省空间的算法来来找出链表中倒数第m个元素补充:类似力扣 剑指 Offer 22. 链表中倒数第k个节点https://leetcode-cn.com/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/题解思路:方法一:双指针函数代码:class Solution {public: ListNode* getKthFromEnd(ListNode* head, int原创 2020-09-01 15:09:30 · 167 阅读 · 0 评论 -
21. 合并两个有序链表
题目:将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。题解思路:方法一:递归函数代码一:l1结点和l2结点比较值大小关系,谁小则是合并链表的头结点,并且返回头结点。class Solution {public: ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { if(!l1) { return l2; }原创 2020-08-14 16:58:37 · 231 阅读 · 0 评论