链表

Posted on August 10, 2021   27 minute read ∼ Filed in  : 

Linked-list related

type ListNode struct {
      Val int
      Next *ListNode
	  
}

1[Medium]. Find the Duplicate Number

// 主要是把list和链表关联起来,首先有索引和值的关系,其次把值也当作索引
// 3,1,3,4,2 可以看作 以下对应关系
// 0 -> 3
// 1 -> 1 
// 2 -> 3
// 3 -> 4
// 4 -> 2, 进而绘制成环
func findDuplicate(nums []int) int {
	slow := 0
	fast := 0
	for {
		slow = nums[slow]
		fast = nums[nums[fast]]
		fmt.Println(slow, fast)
		if  slow == fast {
			break
		}
	}
	// meet
	slow = 0
	for{
		slow = nums[slow]
		fast = nums[fast]
		fmt.Println(slow, fast)
		if  slow == fast {
			return slow
		}
	}
}

2[Easy]. Remove Duplicates from Sorted List

func deleteDuplicates(head *ListNode) *ListNode {
    if head == nil{
        return head
    }
	slow := head
	fast := head.Next
	
  // use slow.next to make sure last pair is checked. 
	for slow.Next!=nil{
		if slow.Val != fast.Val{
			fast = fast.Next
			slow = slow.Next
		}else{
			fast = fast.Next
			slow.Next = fast
		}
	}
	return head
}

3[Medium]. Remove Duplicates from Sorted List II

func deleteDuplicates(head *ListNode) *ListNode {

	if head == nil{
		return head
	}
	// 设置假点和slow点
	slow := &ListNode{-1, head}
	dummy := slow
	fast := head
	// 记录重复的值
	var dup *ListNode
	for fast.Next!=nil{
		// 如果和重复值相等,跳过
		if dup !=nil && fast.Val == dup.Val{
			fast = fast.Next
			continue
		}
		// 更新重复值
		if fast.Val == fast.Next.Val{
			dup = fast
		}else{
			slow.Next = fast
			slow = fast
			fast = fast.Next
		}
	}
	// check the last value
	if dup !=nil && fast.Val == dup.Val{
		slow.Next = nil
	}else{
		slow.Next = fast
	}
	return dummy.Next
}

4[Easy].Reverse Linked List

func reverseList(head *ListNode) *ListNode {
	var dummy *ListNode = nil
	
	slow := dummy
	fast := head
	
	for fast!=nil{
		
		node := fast.Next
		fast.Next = slow
		slow = fast
		fast = node
	}
	return slow
}

5[Medium].Reverse Linked List II


func reverseBetween(head *ListNode, left int, right int) *ListNode {

	// 假点,位于head之前
	var node = &ListNode{-1, head}
	res := node
	// 遍历假点,知道index等于left
	index := 0
	for index+1 < left{
		node = node.Next
		index++
	}
	// 反转后面的前N位,然后和当前假点相连
	if head.Next!=nil{
		node.Next = reverseFistN(node.Next, right-left+1)
	}
	return res.Next
}

func reverseFistN(fast *ListNode, n int) *ListNode{
	var slow *ListNode = nil
	//记录首位
	head := fast
	// 反转前N位, 
	index := 1
	for fast!=nil && index <= n{
		node := fast.Next
		fast.Next = slow
		slow = fast
		fast = node
		index ++
	}
	// 首位和n+1位相连
	head.Next = fast
	return slow
}

6[Hard].Reverse Nodes in k-Group

func reverseKGroup(head *ListNode, k int) *ListNode{
	pre := &ListNode{0, head}
	res := pre
	
	for head != nil{
    // 确定尾部,从0开始遍历
		tail := pre
		for i:=0; i < k;i++{
			tail = tail.Next
			if tail == nil{return res.Next}
		}
		
		// 截断当前sub-LinkedList
		nextHead := tail.Next
		tail.Next = nil
		
		// 反转
		tail = head
		head = reverse(head)
		
		// 相连接
		pre.Next = head
		tail.Next = nextHead
		
		// 移动指针
		pre = tail
		head = nextHead
	}
	return res.Next
}

func reverse(head * ListNode) * ListNode{
	var dummy *ListNode  = nil
	slow := dummy
	fast := head
	for fast!=nil{
		node := fast.Next
		fast.Next = slow
		slow = fast
		fast = node
	}
	return slow
}

7[Easy].Merge Two Sorted Lists

func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode {
	pre := &ListNode{0, nil}
	res := pre
	for l1!=nil && l2!=nil{
		if l1.Val < l2.Val{
			pre.Next = l1
			l1 = l1.Next
		}else{
			pre.Next = l2
			l2 = l2.Next
		}
		pre = pre.Next
	}
	if l1!=nil{
		pre.Next = l1
	}
	if l2!=nil{
		pre.Next = l2
	}
	return res.Next
}

8[Medium].Partition List

func partition(head *ListNode, x int) *ListNode {
	dummy := &ListNode{}
	slow := dummy
	fast := dummy
	node := head
	var slowBegin *ListNode =nil
	var fastBegin *ListNode =nil
	// 依次构造2个不同的linked-list
	for node!=nil{
		if node.Val < x{
			if slowBegin == nil{
				slowBegin=node
			}
			slow.Next = node
			slow = slow.Next
		}else{
			if fastBegin == nil{
				fastBegin=node
			}
			fast.Next = node
			fast = fast.Next
		}
		node = node.Next
	}
	// 首位相连
	slow.Next = fastBegin
	fast.Next = nil
	if slowBegin==nil{return fastBegin}else{return slowBegin}
}

9[Medium].Sort List

//sort the linked list in O(n logn) time and O(1) memory 
func sortList(head *ListNode) *ListNode {
	// 检查head情况
	if head==nil || head.Next==nil{
		return head
	}
	if head.Next.Next==nil{
		if head.Next.Val > head.Val{
			return head
		}else{
			node := head.Next
			head.Next = nil
			node.Next = head
			return node
		}
	}

	// 找中点, O(n)
	index := 1
	trNode := head
	for trNode != nil{
		trNode = trNode.Next
		index++
	}
	mid := index/2

	// 根据中电均分链表
	index = 1
	trNode = head
	var left *ListNode = head
	var right *ListNode
	for trNode != nil{
		trNode = trNode.Next
		index++
		if mid == index{
			right = trNode.Next
			trNode.Next = nil
			break
		}
	}
	// 递归 对左右分别排序
	l1 := sortList(left)
	l2 := sortList(right)
	// 每次递归,返回合并后的值
	return mergeTwoLists(l1, l2)
}

func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode {
	pre := &ListNode{0, nil}
	res := pre
	for l1!=nil && l2!=nil{
		if l1.Val < l2.Val{
			pre.Next = l1
			l1 = l1.Next
		}else{
			pre.Next = l2
			l2 = l2.Next
		}
		pre = pre.Next
	}
	if l1!=nil{
		pre.Next = l1
	}
	if l2!=nil{
		pre.Next = l2
	}
	return res.Next
}

10[Medium]. Reorder List


func reorderList(head *ListNode)  {
	// 中点
	length := 1
	node := head
	for node!=nil{
		node = node.Next
		length++
	}
	mid := length/2

	// partition 链表
	index := 1
	node = head
	var left *ListNode = node
	var right *ListNode
	for node!=nil{
		node = node.Next
		index++
		if index == mid{
			right = node.Next
			node.Next = nil
			break
		}
	}
	// 反转右边的
	right = reverse(right)

  // 链接起来
	var res = &ListNode{0, head}
	for left!=nil && right !=nil{
		res.Next = left
		left = left.Next
		res = res.Next
		res.Next = right
		right = right.Next
		res = res.Next
	}

	if left!=nil{
		res.Next = left
	}
	if right!=nil{
		res.Next = right
	}
}

func reverse(head *ListNode) *ListNode{
	var dummy *ListNode = nil
	slow := dummy
	fast := head
	for fast!=nil{
		node := fast.Next
		fast.Next = slow
		slow = fast
		fast = node
	}
	return slow
}

11[Easy].Linked List Cycle

// using O(1) (i.e. constant) memory?
// 快慢指针,相遇就有环
func hasCycle(head *ListNode) bool {
	slow := head
	fast := head
	step := 0
	for fast!=nil && fast.Next!=nil{
		if step > 0 && slow==fast{
			return true
		}
		fast = fast.Next.Next
		slow = slow.Next
		step ++ 
	}
	return false
}

12[Medium].Linked List Cycle II

func detectCycle(head *ListNode) *ListNode {
	if head==nil || head.Next==nil{
		return nil
	}
	slow := head
	fast := head
	step := 0
	for fast!=nil && fast.Next!=nil{
		if step > 0 && fast==slow{
			break
		}
		slow = slow.Next
		fast = fast.Next.Next
		step ++
	}
	if fast==nil || fast.Next==nil{
		return nil
	}
	slow = head
	step = 1
	for fast!=slow{
		fast = fast.Next
		slow = slow.Next
		step ++ 
	}
	return slow
}

13[Easy].Palindrome Linked List

func isPalindrome(head *ListNode) bool {
    if head.Next == nil || head == nil{
        return true
    }
	// find middle
	length := 1
	node := head
	for node!=nil{
		node = node.Next
		length ++
	}
	mid := length/2

	// partition
	node = head
	index := 1
	left := node
	right := &ListNode{}
	for node!=nil{
		if index == mid{
			right = node.Next
			node.Next = nil
            break
		}
		node = node.Next
		index ++
	}
	// reverse right
	right = reverse(right)
	for left!=nil && right!=nil{
		if left.Val!=right.Val{
			return false
		}
		left = left.Next
		right = right.Next
	}
	return true
}

func reverse(head *ListNode)*ListNode{
	var slow *ListNode = nil
	fast := head
	for fast!=nil{
		node := fast.Next
		fast.Next = slow
		slow = fast
		fast = node
	}
	return slow
}

14[Medium].Copy List with Random Pointer


func copyRandomList(head *Node) *Node {

	// key: 老链的节点,value: 新链的节点
	mapper := make(map[*Node]*Node)

	// 新list的头
	copyHead := &Node{}
	copyNode := copyHead

	// 先复制,并且补充好next的值
	node := head
	for node!=nil{
		newNode := &Node{node.Val, nil, nil}
		copyNode.Next = newNode
		copyNode = copyNode.Next
		mapper[node] = newNode
		node = node.Next
	}
	copyNode.Next = nil
	
	// 再填充random
	node = head
	copyNode = copyHead.Next
	for node!=nil{
		copyNode.Random = mapper[node.Random]
		copyNode = copyNode.Next
		node = node.Next
	}
	return copyHead.Next
}

15[Medium].Design Linked List


// 双端链表
type DLinkList struct{
	Val int
	Pre *DLinkList
	Next *DLinkList
}

func ConstructDLinkList() *DLinkList{
	a := new(DLinkList)
	return a
}

type MyLinkedList struct {
	head *DLinkList
	tail *DLinkList
	length int
}

func Constructor() MyLinkedList {
	ins := MyLinkedList{}
	ins.head = nil
	ins.tail = nil
	ins.length = 0
	return ins
}

func (this *MyLinkedList) Get(index int) int {
	if this.length <= index{
		return -1
	}
	cur := this.head
	for i:=0; i<index; i++{
		cur  = cur.Next
	}
	return cur.Val
}

func (this *MyLinkedList) AddAtHead(val int)  {
	if this.head == nil{
    // 如果头为空,那么意味着没初始化,尾一定为空
		this.head=&DLinkList{val, nil, nil}
		this.tail = this.head
	}else{
    // 刚初始化完,头尾相等,
		if this.head == this.tail{
			this.head = &DLinkList{val, nil, this.tail}
			this.tail.Pre = this.head
		}else{
    // 正常的
			newNode := &DLinkList{val, nil, this.head}
			this.head.Pre = newNode
			this.head = newNode
		}
	}
	this.length++
}

func (this *MyLinkedList) AddAtTail(val int)  {

	if this.tail == nil{
		this.tail=&DLinkList{val, nil, nil}
		this.head = this.tail
	}else{
		if this.head == this.tail{
			this.tail=&DLinkList{val, this.head, nil}
			this.head.Next = this.tail
		}else{
			newNode := &DLinkList{val, this.tail, nil}
			this.tail.Next = newNode
			this.tail = newNode
		}
	}
	this.length++

}


func (this *MyLinkedList) AddAtIndex(index int, val int)  {

	if this.length < index{
		return
	}

	if this.length == index{
		this.AddAtTail(val)
		return
	}

	if index == 0{
		this.AddAtHead(val)
		return
	}

	cur := this.head

	for i:=0; i<index; i++{
		cur  = cur.Next
	}

	newNode := &DLinkList{val, cur.Pre, cur}
	cur.Pre.Next = newNode
	cur.Pre = newNode

	this.length++
}


func (this *MyLinkedList) DeleteAtIndex(index int)  {
	if this.length <= index{
		return
	}
	cur := this.head

	for i:=0; i<index; i++{
		cur  = cur.Next
	}

	if cur !=this.head && cur != this.tail{
		cur.Pre.Next = cur.Next
		cur.Next.Pre = cur.Pre
	}
  // 刚初始化完,头尾相等,头尾都检查一遍,更新各自的值
	if cur == this.head{
		this.head = this.head.Next
		if this.head!=nil{
			this.head.Pre = nil
		}
	}

	if cur == this.tail{
		this.tail = this.tail.Pre
		if this.tail!=nil{
			this.tail.Next = nil
		}
	}

	this.length--

}

16[Medium].Odd Even Linked List

func oddEvenList(head *ListNode) *ListNode {
	if head==nil || head.Next==nil{
		return head
	}
	oddPointer := head
	oddMark := oddPointer
	evenPointer := head.Next
	evenMark := evenPointer
	
  // 必须一次遍历同时生成2个链表
	cur := head.Next.Next
	index := 3

	for cur!=nil{
		if index%2==1{
			oddPointer.Next = cur
			oddPointer = cur
		}else{
			evenPointer.Next = cur
			evenPointer = cur
		}
		cur = cur.Next
		index ++
	}
	evenPointer.Next = nil
	oddPointer.Next = evenMark
	return oddMark
}

17[Medium].Add Two Numbers

func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
	var node *ListNode = nil
	var res *ListNode = nil
	prev := 0
	for l1!=nil || l2!=nil{
		// 如果都存在
		if l1!=nil && l2!=nil{
			value := (l1.Val+l2.Val+ prev)%10
			prev = (l1.Val+l2.Val+ prev)/10
			newNode := &ListNode{value,nil}
			if node == nil{
				node = newNode
				res = newNode
			}else{
				node.Next = newNode
				node = node.Next
			}
			l1 = l1.Next
			l2 = l2.Next
		// 如果l1存在	
		}else if l1!=nil{
			value := (l1.Val+ prev)%10
			prev = (l1.Val+ prev)/10
			newNode := &ListNode{value,nil}
			if node == nil{
				node = newNode
				res = newNode
			}else{
				node.Next = newNode
				node = node.Next
			}
			l1 = l1.Next
		// 如果l2存在
		}else{
			value := (l2.Val+ prev)%10
			prev = (l2.Val+ prev)/10
			newNode := &ListNode{value,nil}
			if node == nil{
				node = newNode
				res = newNode
			}else{
				node.Next = newNode
				node = node.Next
			}
			l2 = l2.Next
		}
	}
	//如果还有进位
	if prev !=0{
		newNode := &ListNode{prev,nil}
		if node == nil{
			node = newNode
			res = newNode
		}else{
			node.Next = newNode
			node = node.Next
		}
	}
	return res
}

18[Medium].Rotate List

func rotateRight(head *ListNode, k int) *ListNode {
	if head == nil{return head}
	// 算长度
	len := 1
	node := head
	for node.Next!=nil{
		len += 1
		node = node.Next
	}
  // 算绝对的反转次数
	k = k%len
	if k == 0{
		return head
	}
  // 记录最后一个点和第一个要反转的点的index
	lastNode := node
	indexLast := len - k
  //第二次遍历,找出要反转的点的前一个点
	node = head
	for index := 0; index+1<indexLast; index++{
		node = node.Next
	}
	res := node.Next
	node.Next = nil
	lastNode.Next = head
	return res
}

19[Medium].Add Two Numbers II





END OF POST




Tags Cloud


Categories Cloud




It's the niceties that make the difference fate gives us the hand, and we play the cards.