//208.反转链表
func reverseList(head *ListNode) *ListNode {
var pre *ListNode //重点:定义链表类型的空指针
cur := head
for cur != nil { //cur指向空循环结束
temp := cur.Next //保存cur下一个结点的地址
cur.Next = pre //反转链表
pre = cur //先移动pre
cur = temp //再移动cur
}
return pre
}
//24.两两交换链表中的结点
func swapPairs(head *ListNode) *ListNode {
dummyhead := new(ListNode)
dummyhead.Next = head
cur := dummyhead
for cur.Next != nil && cur.Next.Next != nil { //注意顺序,如果反过来,若cur.Next为nil,则cur.Next.Next会报空指针错误
temp := cur.Next //保存第1个结点的地址
temp1 := cur.Next.Next.Next //保存第3个结点的地址
cur.Next = temp.Next
cur.Next.Next = temp
temp.Next = temp1
cur = cur.Next.Next
}
return dummyhead.Next //返回值为虚拟头结点的Next
}
//19.删除链表的倒数第N个结点
func removeNthFromEnd(head *ListNode, n int) *ListNode {
dummyhead := new(ListNode)
dummyhead.Next = head
fast, slow := dummyhead, dummyhead
n++ //让n先+1,使得fast先移动n+1步
for n > 0 && fast != nil { //fast != nil避免n超出链表长度
fast = fast.Next
n--
}
for fast != nil { //快慢指针同时移动,最后慢指针在要删除结点的前一个结点处
fast = fast.Next
slow = slow.Next
}
slow.Next = slow.Next.Next //删除结点
return dummyhead.Next
}
//142.环形链表
func detectCycle(head *ListNode) *ListNode {
fast, slow := head, head
for fast != nil && fast.Next != nil { //快指针每次走2个结点,需要保证fast.Next不为nil
fast = fast.Next.Next //快指针每次走2个结点
slow = slow.Next //慢指针每次走1个结点
if fast == slow { //快慢指针相遇
index1 := head //index1从链表起始位置出发
index2 := fast //index2从快慢指针相遇位置出发
for index1 != index2 { //index1和index2相遇处即为环的入口处
index1 = index1.Next
index2 = index2.Next
}
return index1
}
}
return nil
}
// 面试题 02.07. 链表相交
func getIntersectionNode(headA *ListNode, headB *ListNode) *ListNode {
index1, index2 := headA, headB
for index1 != index2 { //index1和index2相交处即为链表相交的起始结点
if index1 != nil {
index1 = index1.Next //index1首先遍历链表headA
} else {
index1 = headB //然后index1遍历链表headB
}
if index2 != nil {
index2 = index2.Next //index2首先遍历链表headB
} else {
index2 = headA //然后index2遍历链表headA
}
}
return index1
}
//141.环形链表
func hasCycle(head *ListNode) bool {
m := make(map[*ListNode]struct{}) //利用哈希表统计遍历过的元素
cur := head
for cur != nil {//遍历链表中所有元素
if _, ok := m[cur]; ok {//如果出现过返回true
return true
}
m[cur] = struct{}{} //如果没有出现过加入哈希表
cur = cur.Next
}
return false//遍历结束后仍为返回则为false
}
//234.回文链表
func isPalindrome(head *ListNode) bool {
// 方法:将值复制到数组中后用双指针法
cur := head
array := []int{}
for cur != nil {
array = append(array, cur.Val)
cur = cur.Next
}
left, right := 0, len(array)-1 //双指针遍历数组
for left < right {
if array[left] == array[right] {
left++
right--
} else {
return false
}
}
return true
}
//21.合并两个有序链表
func mergeTwoLists(list1 *ListNode, list2 *ListNode) *ListNode {
dummyhead := new(ListNode)
if list1 == nil {
return list2
}
if list2 == nil {
return list1
}
p, cur1, cur2 := dummyhead, list1, list2
for cur1 != nil && cur2 != nil {
if cur1.Val <= cur2.Val { //将较小值加入结果集然后移动该list 的指针
p.Next = cur1
cur1 = cur1.Next
} else {
p.Next = cur2
cur2 = cur2.Next
}
p = p.Next
}
//将list1和list2剩余元素加入结果集
if cur1 != nil {
p.Next = cur1
}
if cur2 != nil {
p.Next = cur2
}
return dummyhead.Next
}
//2.两数相加
func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
carry := 0 //记录进位信息
cur1, cur2 := l1, l2
dummyhead := new(ListNode)
cur := dummyhead
for cur1 != nil || cur2 != nil { //默认短的列表后面元素值为0
n1, n2 := 0, 0
if cur1 != nil {
n1 = cur1.Val
cur1 = cur1.Next
}
if cur2 != nil {
n2 = cur2.Val
cur2 = cur2.Next
}
sum := n1 + n2 + carry
sum, carry = sum%10, sum/10
cur.Next = &ListNode{Val: sum} //创建结点
cur = cur.Next //移动指针
}
if carry > 0 { //如果有进位则需要再加一个结点
cur.Next = &ListNode{Val: carry}
}
return dummyhead.Next
}
//146.LRU缓存
type node struct { //链表中的结点的Value
key, value int
}
type LRUCache struct {
cap int
objectMap map[int]*list.Element
list *list.List
}
func Constructor(capacity int) LRUCache {
return LRUCache{
cap: capacity,
objectMap: map[int]*list.Element{},
list: list.New(),
}
}
func (this *LRUCache) Get(key int) int {
if _, ok := this.objectMap[key]; ok {
e := this.objectMap[key]
this.list.MoveToFront(e)
return e.Value.(node).value
} else {
return -1
}
}
func (this *LRUCache) Put(key int, value int) {
if _, ok := this.objectMap[key]; ok {
e := this.objectMap[key]
e.Value = node{key, value}
this.list.MoveToFront(e) //MovetoFront移动旧结点
return
}
//PushFront加入新节点,并加入到objectMap中
this.objectMap[key] = this.list.PushFront(node{key, value})
if len(this.objectMap) > this.cap {
oldnode := this.list.Back()
this.list.Remove(oldnode) //从list中删除元素
delete(this.objectMap, oldnode.Value.(node).key) //从objectMap中删除元素
}
return
}
//146.LRU缓存
package main
import (
"container/list"
"fmt"
)
type Node struct { //链表中的结点的Value
key, value int
}
type LRUCache struct {
cap int
objectMap map[int]*list.Element
lrulist *list.List
}
func Constructor(capacity int) LRUCache {
return LRUCache{
cap: capacity,
objectMap: map[int]*list.Element{},
lrulist: list.New(),
}
}
func (this *LRUCache) Get(key int) int {
if _, ok := this.objectMap[key]; ok {
e := this.objectMap[key]
//将该节点移到链表首部
this.lrulist.MoveToFront(e) //MovetoFront移动旧结点
return e.Value.(Node).value
} else {
return -1
}
}
func (this *LRUCache) Put(key int, value int) {
if _, ok := this.objectMap[key]; ok {
e := this.objectMap[key]
e.Value = Node{key, value} //赋新值
//将该节点移到链表首部
this.lrulist.MoveToFront(e)
return
}
//PushFront加入新节点,并加入到objectMap中
this.objectMap[key] = this.lrulist.PushFront(Node{key, value})
if len(this.objectMap) > this.cap {
oldnode := this.lrulist.Back()
this.lrulist.Remove(oldnode) //Remove移除旧结点
delete(this.objectMap, oldnode.Value.(Node).key) //删除objectMap中的key
}
return
}
func main() {
L := Constructor(2)
L.Put(1, 1)
L.Put(2, 2)
fmt.Printf("L.Get(1): %v\n", L.Get(1))
L.Put(3, 3)
fmt.Printf("L.Get(2): %v\n", L.Get(2))
L.Put(4, 4)
fmt.Printf("L.Get(1): %v\n", L.Get(1))
fmt.Printf("L.Get(3): %v\n", L.Get(3))
fmt.Printf("L.Get(4): %v\n", L.Get(4))
/* L.Get(1): 1
L.Get(2): -1
L.Get(1): -1
L.Get(3): 3
L.Get(4): 4 */
}