leetcode之单链表题目汇总
来源:互联网 发布:联影 算法怎么样 编辑:程序博客网 时间:2024/06/01 20:33
题目】
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
【题意】
给你两个链表,表示两个非负整数。数字在链表中按反序存储,例如342在链表中为2->4->3。链表每一个节点包含一个数字(0-9)。
计算这两个数字和并以链表形式返回。
分析:用链表表示数据,模拟加法, 时间复杂度 O(m+n),空间复杂度 O(1)
}
【题目】
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
.
Note:
Given m, n satisfy the following condition:
1 ≤ m ≤ n ≤ length of list.
【题意】
将给定链表第m个节点到第n个节点的位置逆序,返回逆序后的链表。
给定M,N满足以下条件:
1≤M≤N≤列表的长度。
注意要求:在原地反转,也就是不能申请额外的空间,且只能遍历一遍。
前m-1个不变,从第m+1个到第n个,依次删除,用尾插法插入到第m-1个节点后面。
第一步把4节点删除放入2节点之后
第二步把5节点删除放入2节点之后
【题目】
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
.
【题意】
给定一个链表和一个值x,对它进行分区,使得小于x的所有节点来到大于或等于x的所有节点之前。
你应该保持在每两个分区的节点的原始相对顺序。
方法:
遍历一遍链表,把小于x的都挂到left后,把大于等于x的都放到right后,最后再把大于等于的链表挂到小于链表的后面就可以了。
【题目】
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
.
【题意】
给定一个链表和一个值x,对它进行分区,使得小于x的所有节点来到大于或等于x的所有节点之前。
你应该保持在每两个分区的节点的原始相对顺序。
方法:
遍历一遍链表,把小于x的都挂到left后,把大于等于x的都放到right后,最后再把大于等于的链表挂到小于链表的后面就可以了。
For example,
Given 1->1->2
, return 1->2
.
Given 1->1->2->3->3
, return 1->2->3
.
【题意】
给定一个有序链表,删除所有重复元素,使得每个元素只出现一次。
时间复杂度 O(n),空间复杂度 O(1)
【题目】
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
.
【题意】
给定一个有序链表,删除具有重复的数字,从原来的列表中只留下了不同数字的所有节点。
方法:
遍历链表,记录重复元素的起始位置和截止位置。要删除的重复元素的上一个位置begin,截止位置end。例如:1,2,2,2,4 begin = 0 end = 3
如果当前元素和上一个元素相等,则更新end;如果不相等则判断beigin和end是否相等,相等没有重复元素需要删除,不相等删除[being+1,end]中元素。
【题目】
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
.
【题意】
给定一个链表,向右旋转k个位置,其中k是非负的。
方法一:
先遍历一遍,得出链表长度 len,注意 k 可能大于 len,因此令 k% = len。将尾节点 next 指针
指向首节点,形成一个环,接着往后跑 len - k 步,从这里断开,就是要求的结果了。
方法二:
【题目】
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.
【题意】
给你一个链表,去除掉倒数第n个节点。
方法一:遍历链表两遍(不符合题意)
方法二:遍历一遍数组
设两个指针 p; q,让 q 先走 n 步,然后 p 和 q 一起走,直到 q 走到尾节点,删除 p->next 即可。
【题目】
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.
【题意】
给定一个链表,交换每两个相邻的节点,并返回它的头。
你的算法应该使用常数空间。不得修改在列表中的值,只有节点本身是可以改变的。
【题目】
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
【题意】
对链表中的元素按K个一组,反序后,形成新的链表。对于最后不满K个元素,保持原来的顺序输出。
方法一:
方法二:
1、建立空的新链表list1.
2、如果原链表剩余元素个数不小于K个,则取K个元素,采用头插法构建反序的临时链表,插入list1的尾部。
3、如果链表剩余元素个数小于K个,则将剩余的链表插入到list1的尾部。
Return a deep copy of the list.
【题意】
深拷贝一个链表,链表除了含有next指针外,还包含一个random指针,该指针指向链表中的某个节点或者为空。【方法一】暴力复制,时间复杂度O(n^2)
【算法二】时间复杂度O(N),空间复杂度O(1)
不用保存原始链表的映射关系,构建新节点时,指针做如下变化,即把新节点插入到相应的旧节点后面:
同理分两步
1、构建新节点random指针:new1->random = old1->random->next, new2-random = NULL, new3-random = NULL, new4->random = old4->random->next
2、恢复原始链表以及构建新链表:例如old1->next = old1->next->next, new1->next = new1->next->next
【题目】
Given a linked list, determine if it has a cycle in it.
Follow up:
Can you solve it without using extra space?
【题意】
给定一个链表,判断它是否包含一个环。
【注意】
1. 空链表不成环
2. 一个节点自环
3. 一条链表完整成环
【方法一】 空间复杂度 O(n),时间复杂度 O(N )
用一个哈希表 unordered_map<ListNode *, bool> visited,记录每个元素是否被访问过,一旦出现某个元素被重复访问,说明存在环。
。
使用两个指针slow,fast。两个指针都从表头开始走,slow每次走一步,fast每次走两步,如果fast遇到null,则说明没有环,返回false;如果slow==fast,说明有环,并且此时fast超了slow一圈,返回true。
为什么有环的情况下二者一定会相遇呢?因为fast先进入环,在slow进入之后,如果把slow看作在前面,fast在后面每次循环都向slow靠近1,所以一定会相遇,而不会出现fast直接跳过slow的情况。
这里需要注意的一点是算法中循环的条件,这是一个很容易被忽略的细节。
1)因为fast指针比slow指针走得快,所以只要判断fast指针是否为空就好。由于fast指针一次走两步,fast.next可能已经为空(当fast为尾结点时),fast.next.next将会导致NullPointerException异常,所以在while循环中我们要判断fast.next是否为空;
2)考虑一个特殊情况,当输入的链表为空时,算法应该返回false,空链表肯定是不含有环的。如果没有fast != null,也会导致fast.next抛出NullPointerException异常。
题目:
Given a linked list, return the node where the cycle begins. If there is no cycle, return null
.
Follow up: Can you solve it without using extra space?
题意:
如何找到环的第一个节点?
分析:
1)先判断是否存在环
使用两个指针slow,fast。两个指针都从表头开始走,slow每次走一步,fast每次走两步,如果fast遇到null,则说明没有环,返回false;如果slow==fast,说明有环,并且此时fast超了slow一圈,返回true。
为什么有环的情况下二者一定会相遇呢?因为fast先进入环,在slow进入之后,如果把slow看作在前面,fast在后面每次循环都向slow靠近1,所以一定会相遇,而不会出现fast直接跳过slow的情况。
2)找环的第一个节点
设:链表头是X,环的第一个节点是Y,slow和fast第一次的交点是Z。各段的长度分别是a,b,c,如图所示。环的长度是L。slow和fast的速度分别是qs,qf。
第一次相遇时slow走过的距离:a+b,fast走过的距离:a+b+c+b。
因为fast的速度是slow的两倍,所以fast走的距离是slow的两倍,有 2(a+b) = a+b+c+b,可以得到a=c(这个结论很重要!)。
发现L=b+c=a+b,也就是说,从一开始到二者第一次相遇,循环的次数就等于环的长度。
已经得到了结论a=c,那么让两个指针分别从X和Z开始走,每次走一步,那么正好会在Y相遇!也就是环的第一个节点。
【题目拓展】
1. 环的长度是多少?
方法一:
第一次相遇后,让fast停着不走了,slow继续走,记录到下次相遇时循环了几次。
方法二:
第一次相遇时slow走过的距离:a+b,fast走过的距离:a+b+c+b。
因为fast的速度是slow的两倍,所以fast走的距离是slow的两倍,有 2(a+b) = a+b+c+b,可以得到a=c(这个结论很重要!)。
我们发现L=b+c=a+b,也就是说,从一开始到二者第一次相遇,循环的次数就等于环的长度。
2. 如何找到环中第一个节点(即Linked List Cycle II)?
我们已经得到了结论a=c,那么让两个指针分别从X和Z开始走,每次走一步,那么正好会在Y相遇!也就是环的第一个节点。
3. 如何将有环的链表变成单链表(解除环)?
在上一个问题的最后,将c段中Y点之前的那个节点与Y的链接切断即可。
4. 如何判断两个单链表是否有交点?如何找到第一个相交的节点?
先判断两个链表是否有环,如果一个有环一个没环,肯定不相交;如果两个都没有环,判断两个列表的尾部是否相等;如果两个都 有环,判断一个链表上的Z点是否在另一个链表上。
5、(接问题4)如何找到第一个相交的节点?
求出两个链表的长度L1,L2(如果有环,则将Y点当做尾节点来算),假设L1<L2,用两个指针分别从两个链表的头部开始走,长度 为L2的链表先走(L2-L1)步,然后两个一起走,直到二者相遇。
【题目】
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}
.
【题意】
给定一个单链表L:L0→L1→...→LN-1→LN,
它重新排列到:L0→LN→L1→LN-1→L2→LN-2→...
【分析】
题目规定要 in-place,也就是说只能使用 O(1) 的空间。
可以找到中间节点,断开,把后半截单链表 reverse 一下,再合并两个单链表。
- leetcode之单链表题目汇总
- LeetCode之Array题目汇总
- LeetCode之Math题目汇总
- LeetCode之String题目汇总
- LeetCode之Backtracing题目汇总
- LeetCode之Stack题目汇总
- LeetCode之Sort题目汇总
- LeetCode之Tree题目汇总
- LeetCode之Graph题目汇总
- LeetCode之Trie题目汇总
- LeetCode之Design题目汇总
- LeetCode之Hash Table题目汇总
- LeetCode之Linked List题目汇总
- LeetCode之Binary Search题目汇总
- LeetCode之Divide and Conquer题目汇总
- LeetCode之Dynamic Programming题目汇总
- LeetCode之Bit Manipulation题目汇总
- LeetCode之Depth-first Search题目汇总
- 数值得整数次方--模拟pow函数的功能
- csapp 实验二 二进制炸弹
- 利用Android Studio的CMake来快速开发NDK
- multipart/form-data post 方法提交表单,后台获取不到数据
- C++ primer plus 阅读记录-使用类
- leetcode之单链表题目汇总
- bat脚本学习 --参数传递
- lua中table操作的相关函数
- html5的学习笔记
- 深度神经网络结构以及Pre-Training的理解
- Java8:函数式编程与Lambda表达式
- JS设置页面下拉刷新
- java web项目内存溢出
- Qt之描绘轮廓