NC78 反转链表
描述
给定一个单链表的头结点pHead,长度为n,反转该链表后,返回新链表的表头。
数据范围: n\leq1000n≤1000
要求:空间复杂度 O(1)O(1) ,时间复杂度 O(n)O(n) 。
如当输入链表{1,2,3}时,
经反转后,原链表变为{3,2,1},所以对应的输出为{3,2,1}。
以上转换过程如下图所示:
示例1
输入:
1 | {1,2,3} |
返回值:
1 | {3,2,1} |
复制
示例2
输入:
1 | {} |
返回值:
1 | {} |
说明:
1 | 空链表则输出空 |
思路:
- 利用next往head列表下一步走
- 利用pre来保存拼接信息
解答:
1 | public class Solution { |
NC4 判断链表中是否有环
描述
判断给定的链表中是否有环。如果有环则返回true,否则返回false。
数据范围:链表长度 0 \le n \le 100000≤n≤10000,链表中任意节点的值满足 |val| <= 100000∣val∣<=100000
要求:空间复杂度 O(1)O(1),时间复杂度 O(n)O(n)
输入分为2部分,第一部分为链表,第二部分代表是否有环,然后将组成的head头结点传入到函数里面。-1代表无环,其它的数字代表有环,这些参数解释仅仅是为了方便读者自测调试。实际在编程时读入的是链表的头节点。
例如输入{3,2,0,-4},1时,对应的链表结构如下图所示:
可以看出环的入口结点为从头结点开始的第1个结点,所以输出true。
示例1
输入:
1 | {3,2,0,-4},1 |
返回值:
1 | true |
说明:
1 | 第一部分{3,2,0,-4}代表一个链表,第二部分的1表示,-4到位置1,即-4->3存在一个链接,组成传入的head为一个带环的链表,返回true |
示例2
输入:
1 | {1},-1 |
返回值:
1 | false |
说明:
1 | 第一部分{1}代表一个链表,-1代表无环,组成传入head为一个无环的单链表,返回false |
示例3
输入:
1 | {-1,-7,7,-4,19,6,-9,-5,-2,-5},6 |
返回值:
1 | true |
思路:
- 构建快慢指针
- 快的走两步,慢的走一步
- 判断每次只能判断当前与下一步的所指情况,否则容易出现越界的问题(null.next)
解答:
1 | public class Solution { |
NC3 链表中环的入口结点
描述
给一个长度为n链表,若其中包含环,请找出该链表的环的入口结点,否则,返回null。
数据范围:n*≤10000,1<=结点值<=10000
要求:空间复杂度 O(1),时间复杂度 O(n)
例如,输入{1,2},{3,4,5}时,对应的环形链表如下图所示:
可以看到环的入口结点的结点值为3,所以返回结点值为3的结点。
输入描述:
输入分为2段,第一段是入环前的链表部分,第二段是链表环的部分,后台会根据第二段是否为空将这两段组装成一个无环或者有环单链表
返回值描述:
返回链表的环的入口结点即可,我们后台程序会打印这个结点对应的结点值;若没有,则返回对应编程语言的空结点即可。
示例1
输入:
1 | {1,2},{3,4,5} |
返回值:
1 | 3 |
说明:
1 | 返回环形链表入口结点,我们后台程序会打印该环形链表入口结点对应的结点值,即3 |
示例2
输入:
1 | {1},{} |
返回值:
1 | "null" |
说明:
1 | 没有环,返回对应编程语言的空结点,后台程序会打印"null" |
示例3
输入:
1 | {},{2} |
返回值:
1 | 2 |
说明:
1 | 环的部分只有一个结点,所以返回该环形链表入口结点,后台程序打印该结点对应的结点值,即2 |
思路:
- 设置快慢指针,假如有环,他们最后一定相遇。
- 两个指针分别从链表头和相遇点继续出发,每次走一步,最后一定相遇与环入口。
解答:
1 | /* |
NC50 链表中的节点每k个一组翻转
描述
将给出的链表中的节点每 k 个一组翻转,返回翻转后的链表
如果链表中的节点数不是 k 的倍数,将最后剩下的节点保持原样
你不能更改节点中的值,只能更改节点本身。
数据范围: \ 0 \le n \le 2000 0≤n≤2000 , 1 \le k \le 20001≤k≤2000 ,链表中每个元素都满足 0 \le val \le 10000≤val≤1000
要求空间复杂度 O(1)O(1),时间复杂度 O(n)O(n)
例如:
给定的链表是 1\to2\to3\to4\to51→2→3→4→5
对于 k = 2k=2 , 你应该返回 2\to 1\to 4\to 3\to 52→1→4→3→5
对于 k = 3k=3 , 你应该返回 3\to2 \to1 \to 4\to 53→2→1→4→5
示例1
输入:
1 | {1,2,3,4,5},2 |
返回值:
1 | {2,1,4,3,5} |
示例2
输入:
1 | {},1 |
返回值:
1 | {} |
思路:
- 写一个计算链表长度的子函数,并对链表进行分块
- 设置一个result存返回值,一个now=result对now进行操作,实际改变了result的值
- 每一块进行反转
- 一个for循环,每次head向前移一位
- head.next存tmp
- tmp存当前head值
解答:
1 | import java.util.*; |
NC96 判断一个链表是否为回文结构
描述
给定一个链表,请判断该链表是否为回文结构。
回文是指该字符串正序逆序完全一致。
数据范围: 链表节点数 0 \le n \le 10^70≤n≤107,链表中每个节点的值满足 |val| \le 10^7∣val∣≤107
示例1
输入:
1 | {1} |
返回值:
1 | true |
示例2
输入:
1 | {2,1} |
返回值:
1 | false |
说明:
1 | 2->1 |
示例3
输入:
1 | {1,2,2,1} |
返回值:
1 | true |
说明:
1 | 1->2->2->1 |
思路:
- a链表=b链表 a变b也变
- 快慢指针找到中点
- 只反转后半段
解答:
1 | import java.util.*; |
NC40 两个链表生成相加链表
描述
假设链表中每一个节点的值都在 0 - 9 之间,那么链表整体就可以代表一个整数。
给定两个这种链表,请生成代表两个整数相加值的结果链表。
数据范围:0 \le n,m \le 10000000≤n,m≤1000000,链表任意值 0 \le val \le 90≤val≤9
要求:空间复杂度 O(n)O(n),时间复杂度 O(n)O(n)
例如:链表 1 为 9->3->7,链表 2 为 6->3,最后生成新的结果链表为 1->0->0->0。
示例1
输入:
1 | [9,3,7],[6,3] |
返回值:
1 | {1,0,0,0} |
说明:
1 | 如题面解释 |
示例2
输入:
1 | [0],[6,3] |
返回值:
1 | {6,3} |
备注:
1 | 1 \leq n, m \leq 10^61≤n,m≤106 |
思路:
- 反转相加,注意进位
- 构造新的链表 (一定得有初始值) ListNode head = new ListNode(-1);
- 添加链表的节点需要new一个新的链表 cur.next = new ListNode(val % 10)
解答:
1 | import java.util.*; |
剑指 Offer II 077. 链表排序
给定链表的头结点 head
,请将其按 升序 排列并返回 排序后的链表 。
示例 1:
1 | 输入:head = [4,2,1,3] |
示例 2:
1 | 输入:head = [-1,5,3,4,0] |
示例 3:
1 | 输入:head = [] |
解答:
- 先存入数组,然后sort排序,然后存回链表
1 | /** |