lc.61 旋转链表
题目描述
给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k **个位置。
- 链表中节点的数目在范围 [0, 500] 内
- -100 <= Node.val <= 100
- 0 <= k <= 2 * 109
思路
观察链表,可能会出现后部节点出现在链表开头情况,因此可以想到用环形链表解决
首尾连起来后,只需要根据K将 需要作为头节点的节点找到,再断开该头节点与前一个节点的联系就完成了。
将新头节点称作newHead,如何通过k找到newHead?
可以发现,k=1时newHead为第5个节点,k=2时为第4个节点。
因此,设链表长度为count,可以推得 newHead为 count-k+1个节点(k<count时)
由于k可以大于count,因此需要对k做处理,即k = k % count
代码
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func rotateRight(head *ListNode, k int) *ListNode {
if head==nil||head.Next==nil||k==0{
return head
}
count := 1
last := head
// 找到最后一个节点
for last.Next!=nil{
count++
last = last.Next
}
last.Next = head
k = k%count
move := count - k
cur := head
pre := &ListNode{}
for move!=0{
pre = cur
cur = cur.Next
move--
}
pre.Next = nil
return cur
}
\
lc.138 复制带随机指针的链表
题目描述
现在有一条链表,链表中的每个节点存储了该节点值、下一个节点以及一个随机节点(可以为null)
现在任务是,深拷贝一条该链表,该链表所有节点和原链表地址不同,需要保留相同的链表状态、各个节点的对应关系。
- 0 <= n <= 1000
- -104 <= Node.val <= 104
- Node.random 为 null 或指向链表中的节点。
思路
遍历所有节点,针对每一个节点都复制三个节点,包括它本身,它的next节点以及random节点
这样的话保留了对应关系,但是会出现重复复制节点的现象
理想状况下,在复制节点并赋值时,假如检测到已经复制过该节点了,就直接将该节点的复制体返回。
这就需要能够检测该节点是否重复复制,以及能取到该复制体的地址。
使用哈希表的方式来保存复制体。使用dfs来遍历节点,一边遍历一边检测一边复制。
key为原链表节点,value为复制链表的节点,每复制一个就往哈希表填入键值对
代码
/**
* Definition for a Node.
* type Node struct {
* Val int
* Next *Node
* Random *Node
* }
*/
func copyRandomList(head *Node) *Node {
hash:=make(map[*Node]*Node)
return dfs(head,hash)
}
func dfs(cur *Node,hash map[*Node]*Node) *Node{
if cur==nil{
return nil
}
if _,ok := hash[cur];ok{
return hash[cur] // 如果已经复制过了,就直接返回该复制体
}
clone := &Node{Val:cur.Val}
hash[cur] = clone
clone.Next = dfs(cur.Next,hash)
clone.Random = dfs(cur.Random,hash)
return clone
}