# Hot 100

23 min read
Table of Contents

梦开始的地方

哈希

1. 两数之和

两数之和

暴力枚举

func twoSum(nums []int, target int) []int {
left := 0
for left < len(nums) {
right := left + 1
for right < len(nums) {
if nums[left] + nums[right] == target {
return []int{left, right}
}
right++
}
left++
}
return []int{}
}

哈希表

func twoSum(nums []int, target int) []int {
hashMap := make(map[int]int)
for i := 0; i < len(nums); i++ {
wanted := target - nums[i]
if index, ok := hashMap[wanted]; ok {
return []int{index, i}
}
hashMap[nums[i]] = i
}
return nil
}

49. 字母异位词分组

字母异位词分组

排序 哈希表

func groupAnagrams(strs []string) [][]string {
var ans [][]string
hashMap := make(map[string][]string)
for _, str := range strs {
s := []byte(str)
sort.Slice(s, func(i, j int) bool { return s[i] < s[j] })
sortedStr := string(s)
hashMap[sortedStr] = append(hashMap[sortedStr], str)
}
for _, part := range hashMap {
ans = append(ans, part)
}
return ans
}

存字母计数向量

func groupAnagrams(strs []string) [][]string {
hashMap := make(map[[26]int][]string)
for _, str := range strs {
cnt := [26]int{}
for _, b := range str {
cnt[b-'a']++
}
hashMap[cnt] = append(hashMap[cnt], str)
}
var ans [][]string
for _, v := range hashMap {
ans = append(ans, v)
}
return ans
}

128. 最长连续序列

最长连续序列

排序

func longestConsecutive(nums []int) int {
sort.Slice(nums, func(i, j int) bool { return nums[i] < nums[j] })
cur := 1
maxNum := 1
if len(nums) == 0 {
return 0
}
if len(nums) == 1 {
return 1
}
pre := nums[0]
for i := 1; i < len(nums); i++ {
if nums[i] == pre {
continue
}
if nums[i] == pre + 1 {
cur++
} else if nums[i] > pre + 1 {
maxNum = max(cur, maxNum)
cur = 1
}
pre = nums[i]
}
return max(maxNum, cur)
}

官方题解没给排序,结果排序更快且内存更少,那是何意味

哈希表去重

func longestConsecutive(nums []int) int {
numSet := make(map[int]bool)
for _, num := range nums {
numSet[num] = true
}
longestStreak := 0
for num := range numSet {
if !numSet[num - 1] {
currentNum := num
currentStreak := 1
for numSet[currentNum + 1] {
currentNum++
currentStreak++
}
if longestStreak < currentStreak {
longestStreak = currentStreak
}
}
}
return longestStreak
}

双指针

283. 移动零

移动零

双指针交换

func moveZeroes(nums []int) {
left := 0
for right := 0; right < len(nums); right++ {
if nums[right] != 0 {
nums[left], nums[right] = nums[right], nums[left]
left++
}
}
}

11. 盛最多水的容器

盛最多水的容器

双指针+贪心

func maxArea(height []int) int {
left, right := 0, len(height) - 1
var s, ans int
for left < right {
s = (right - left)*min(height[left], height[right])
if s > ans {
ans = s
}
if height[left] >= height[right] {
right--
} else {
left++
}
}
return ans
}

15. 三数之和

三数之和

定1双指针另外两个

func threeSum(nums []int) [][]int {
var ans [][]int
sort.Slice(nums, func(i, j int) bool { return nums[i] <= nums[j] })
for i := 0; i < len(nums)-2; i++ {
if i > 0 && nums[i - 1] == nums[i] {
continue
}
x := nums[i]
left := i + 1
right := len(nums) - 1
for left < right {
y := nums[left] + nums[right]
if y + x == 0 {
ans = append(ans, []int{x, nums[left], nums[right]})
for nums[right] == nums[right - 1] && left < right {
right--
}
for nums[left] == nums[left + 1] && left < right {
left++
}
left++
right--
} else if y + x > 0 {
right--
} else if y + x < 0 {
left++
}
}
}
return ans
}

可以稍微优化一点

+剪枝+语法优化

func threeSum(nums []int) [][]int {
slices.Sort(nums)
length := len(nums)
ans := make([][]int, 0)
for i, num := range nums {
if num > 0 {
break
}
if i > 0 && nums[i - 1] == num {
continue
}
target := -num
left, right := i + 1, length - 1
for left < right {
sum := nums[left] + nums[right]
if sum > target {
right--
} else if sum < target {
left++
} else {
for left < right && nums[left] == nums[left + 1] {
left++
}
for left < right && nums[right] == nums[right - 1] {
right--
}
ans = append(ans, []int{num, nums[left], nums[right]})
left++
right--
}
}
}
return ans
}

slices.Sort相比sort.Slice 前者为泛型排序,不用闭包性能更好

nSum

func nSum(nums []int, n int, start int, target int) [][]int {
res := [][]int{}
length := len(nums)
if n < 2 || length-start < n {
return res
}
if n == 2 {
left, right := start, length-1
for left < right {
sum := nums[left] + nums[right]
if sum == target {
res = append(res, []int{nums[left], nums[right]})
for left < right && nums[left] == nums[left+1] {
left++
}
for left < right && nums[right] == nums[right-1] {
right--
}
left++
right--
} else if sum < target {
left++
} else {
right--
}
}
return res
}
for i := start; i < length; i++ {
if i > start && nums[i] == nums[i-1] {
continue
}
if nums[i]*n > target {
break
}
if nums[length-1]*n < target {
break
}
sub := nSum(nums, n-1, i+1, target-nums[i])
for _, arr := range sub {
res = append(res, append([]int{nums[i]}, arr...))
}
}
return res
}

42. 接雨水

接雨水

长官我只会双指针

func trap(height []int) int {
l := len(height)
left := 0
right := l - 1
leftMax := 0
rightMax := 0
ans := 0
for left < right {
leftMax = max(leftMax, height[left])
rightMax = max(rightMax, height[right])
if height[left] < height[right] {
ans += leftMax - height[left]
left++
} else {
ans += rightMax - height[right]
right--
}
}
return ans
}

滑动窗口

3. 无重复字符的最长子串

无重复字符的最长子串

哈希+滑动窗口

func lengthOfLongestSubstring(s string) int {
hashMap := make(map[byte]bool)
left := 0
maxLen := 0
for right := 0; right < len(s); right++ {
for hashMap[s[right]] {
delete(hashMap, s[left])
left++
}
hashMap[s[right]] = true
if right - left + 1 > maxLen {
maxLen = right - left + 1
}
}
return maxLen
}

4ms

+写法优化

func lengthOfLongestSubstring(s string) int {
res, left := 0, 0
cnt := [128]int{}
for right := 0; right < len(s); right++ {
cnt[s[right]]++
for cnt[s[right]] >= 2 {
cnt[s[left]]--
left++
}
res = max(res, right-left+1)
}
return res
}

0ms

438. 找到字符串中所有字母异位词

找到字符串中所有字母异位词

定长窗口 26字母

func findAnagrams(s string, p string) []int {
sLen, pLen := len(s), len(p)
if sLen < pLen {
return []int{}
}
ans := []int{}
var sCount, pCount [26]int
for i, ch := range p {
sCount[s[i]-'a']++
pCount[ch-'a']++
}
if pCount == sCount {
ans = append(ans, 0)
}
for i, ch := range s[:sLen - pLen] {
sCount[ch-'a']--
sCount[s[i+pLen]-'a']++
if sCount == pCount {
ans = append(ans, i + 1)
}
}
return ans
}

子串

560. 和为 K 的子数组

和为 K 的子数组

暴力+前缀和

func subarraySum(nums []int, k int) int {
n := len(nums)
sum := make([]int, n+1)
for i := 0; i < n; i++ {
sum[i+1] = sum[i] + nums[i]
}
ans := 0
for i := 0; i < n; i++ {
for j := i; j < n; j++ {
if sum[j+1]-sum[i] == k {
ans++
}
}
}
return ans
}

哈希表+前缀和

func subarraySum(nums []int, k int) int {
count := 0
prefix := 0
m := map[int]int{0: 1}
for _, num := range nums {
prefix += num
if v, ok := m[prefix-k]; ok {
count += v
}
m[prefix]++
}
return count
}

239. 滑动窗口最大值

滑动窗口最大值

双端队列

func maxSlidingWindow(nums []int, k int) []int {
n := len(nums)
var ans []int
deque := []int{}
for i := 0; i < n; i++ {
if len(deque) > 0 && deque[0] < i-k+1 {
deque = deque[1:]
}
for len(deque) > 0 && nums[deque[len(deque)-1]] < nums[i] {
deque = deque[:len(deque)-1]
}
deque = append(deque, i)
if i >= k-1 {
ans = append(ans, nums[deque[0]])
}
}
return ans
}

但这样写没有这个写法快

func maxSlidingWindow(nums []int, k int) []int {
if len(nums) == 0 || k == 0 {
return []int{}
}
n := len(nums)
result := make([]int, 0, n - k + 1)
deque := make([]int, 0 , k)
for i := 0; i < n; i++ {
if len(deque) > 0 && deque[0] < i - k + 1 {
deque = deque[1:]
}
for len(deque) > 0 && nums[deque[len(deque) - 1]] < nums[i] {
deque = deque[:len(deque) - 1]
}
deque = append(deque, i)
if i >= k-1 {
result = append(result, nums[deque[0]])
}
}
return result
}

区别就在result := make([]int, 0, n - k + 1)deque := make([]int, 0 , k) 就单单因为提前分配了容量 make(type, size, cap) 第一个为8ms而第二个为1ms

这不神奇吗

76. 最小覆盖子串

最小覆盖子串

滑动窗口+哈希表

func minWindow(s string, t string) string {
need := make(map[byte]int)
window := make(map[byte]int)
for i := 0; i < len(t); i++ {
need[t[i]]++
}
left, count := 0, 0
start, minLen := 0, len(s)+1
for right := 0; right < len(s); right++ {
c := s[right]
if _, ok := need[c]; ok {
window[c]++
if window[c] == need[c] {
count++
}
}
for count == len(need) {
if right-left+1 < minLen {
start = left
minLen = right-left+1
}
d := s[left]
left++
if _, ok := need[d]; ok {
if window[d] == need[d] {
count--
}
window[d]--
}
}
}
if minLen == len(s) + 1 {
return ""
}
return s[start : start + minLen]
}

29ms

func minWindow(s string, t string) string {
n, m := len(s), len(t)
if n < m {
return ""
}
var c1, c2 [60]int
tot := 0
for i := 0; i < m; i++ {
idx := getIdx(t[i])
if c1[idx] == 0 {
tot++
}
c1[idx]++
}
ans := ""
for i, j := 0, 0; i < n; i++ {
idx1 := getIdx(s[i])
c2[idx1]++
if c2[idx1] == c1[idx1] {
tot--
}
for j < i {
idx2 := getIdx(s[j])
if c2[idx2] > c1[idx2] {
c2[idx2]--
j++
} else {
break
}
}
if tot == 0 {
if ans == "" || len(ans) > i-j+1 {
ans = s[j : i+1]
}
}
}
return ans
}
func getIdx(x byte) int {
if x >= 'A' && x <= 'Z' {
return int(x - 'A' + 26)
}
return int(x - 'a')
}

0ms

普通数组

53. 最大子数组和

最大子数组和

前缀和

func maxSubArray(nums []int) int {
minPre := 0
curPre := 0
maxSum := nums[0]
for _, x := range nums {
curPre += x
if curPre - minPre > maxSum {
maxSum = curPre - minPre
}
if curPre < minPre {
minPre = curPre
}
}
return maxSum
}

分治

不太会,以后再说

func maxSubArray(nums []int) int {
return get(nums, 0, len(nums) - 1).mSum;
}
func pushUp(l, r Status) Status {
iSum := l.iSum + r.iSum
lSum := max(l.lSum, l.iSum + r.lSum)
rSum := max(r.rSum, r.iSum + l.rSum)
mSum := max(max(l.mSum, r.mSum), l.rSum + r.lSum)
return Status{lSum, rSum, mSum, iSum}
}
func get(nums []int, l, r int) Status {
if (l == r) {
return Status{nums[l], nums[l], nums[l], nums[l]}
}
m := (l + r) >> 1
lSub := get(nums, l, m)
rSub := get(nums, m + 1, r)
return pushUp(lSub, rSub)
}
func max(x, y int) int {
if x > y {
return x
}
return y
}
type Status struct {
lSum, rSum, mSum, iSum int
}

56. 合并区间

合并区间

一般通过写法

func merge(intervals [][]int) [][]int {
var ans [][]int
var left, right int
sort.Slice(intervals, func(i, j int) bool { return intervals[i][0] < intervals[j][0] })
for i := 0; i < len(intervals); i++ {
left = intervals[i][0]
right = intervals[i][1]
for i < len(intervals)-1 && intervals[i+1][0] <= right {
right = max(intervals[i+1][1], right)
i++
}
ans = append(ans, []int{left, right})
}
return ans
}

排序+原地修改

func merge(intervals [][]int) [][]int {
if (len(intervals) == 1) {
return intervals
}
sort.Slice(intervals, func(i, j int) bool {
return intervals[i][0] < intervals[j][0]
})
res := make([][]int, 0)
res = append(res, intervals[0])
for i := 1; i < len(intervals); i++ {
if (res[len(res)-1][1] >= intervals[i][0]) {
res[len(res)-1][1] = max(res[len(res)-1][1], intervals[i][1])
} else {
res = append(res, intervals[i])
}
}
return res
}

189. 轮转数组

轮转数组

3次翻转

func rotate(nums []int, k int) {
k %= len(nums)
reverse(nums)
reverse(nums[:k])
reverse(nums[k:])
}
func reverse(nums []int) {
for i, n := 0, len(nums); i < n/2; i++ {
nums[i], nums[n-1-i] = nums[n-1-i], nums[i]
}
}

238. 除了自身以外数组的乘积

除了自身以外数组的乘积

前缀积 后缀积

func productExceptSelf(nums []int) []int {
l := len(nums)
ans := make([]int, l)
ans[0] = 1
for i := 1; i < l; i++ {
ans[i] = nums[i-1] * ans[i-1]
}
R := 1
for i := l - 1; i >= 0; i-- {
ans[i] = ans[i] * R
R *= nums[i]
}
return ans
}

41. 缺失的第一个正数

缺失的第一个正数

原地 哈希表

func firstMissingPositive(nums []int) int {
l := len(nums)
for i := 0; i < l; i++ {
if nums[i] <= 0 {
nums[i] = l + 1
}
}
for i := 0; i < l; i++ {
num := abs(nums[i])
if num <= l {
nums[num - 1] = -abs(nums[num - 1]) // 打标
}
}
for i := 0; i < l; i++ {
if nums[i] > 0 {
return i + 1
}
}
return l + 1
}
func abs(x int) int {
if x < 0 {
return -x
}
return x
}

矩阵

73. 矩阵置零

矩阵置零

两标记

func setZeroes(matrix [][]int) {
n, m := len(matrix), len(matrix[0])
// 第一行 第一列 提前维护
row0, col0 := false, false
for _, v := range matrix[0] {
if v == 0 {
row0 = true
break
}
}
for _, r := range matrix {
if r[0] == 0 {
col0 = true
break
}
}
for i := 1; i < n; i++ {
for j := 1; j < m; j++ {
if matrix[i][j] == 0 {
matrix[i][0] = 0
matrix[0][j] = 0
}
}
}
for i := 1; i < n; i++ {
for j := 1; j < m; j++ {
if matrix[i][0] == 0 || matrix[0][j] == 0 {
matrix[i][j] = 0
}
}
}
if row0 {
for j :=0; j < m; j++ {
matrix[0][j] = 0
}
}
if col0 {
for i := 0; i < n; i++ {
matrix[i][0] = 0
}
}
}

一标记

我不喜欢

没2直观

func setZeroes(matrix [][]int) {
n, m := len(matrix), len(matrix[0])
col0 := false
for _, r := range matrix {
if r[0] == 0 {
col0 = true
}
for j := 1; j < m; j++ {
if r[j] == 0 {
r[0] = 0
matrix[0][j] = 0
}
}
}
for i := n - 1; i >= 0; i-- {
for j := 1; j < m; j++ {
if matrix[i][0] == 0 || matrix[0][j] == 0 {
matrix[i][j] = 0
}
}
if col0 {
matrix[i][0] = 0
}
}
}

54. 螺旋矩阵

螺旋矩阵

按逻辑遍历

func spiralOrder(matrix [][]int) []int {
ans := []int{}
n, m := len(matrix[0]), len(matrix)
top, bottom, left, right := 0, m - 1, 0, n - 1
for top <= bottom && left <= right {
// 右
for i := left; i <= right; i++ {
ans = append(ans,matrix[top][i])
}
top++
// 下
for i := top; i <= bottom; i++ {
ans = append(ans,matrix[i][right])
}
right--
// 左
if top <= bottom {
for i := right; i >= left; i-- {
ans = append(ans,matrix[bottom][i])
}
bottom--
}
// 上
if left <= right {
for i := bottom; i >= top; i-- {
ans = append(ans,matrix[i][left])
}
left++
}
}
return ans
}

48. 旋转图像

旋转图像

对角线折叠 行对称

func rotate(matrix [][]int) {
n := len(matrix)
for i := 0; i < n; i++ {
for j := i; j < n; j++ {
matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
}
}
for i := 0; i < n; i++ {
for j := 0; j < n/2; j++ {
matrix[i][j],matrix[i][n-1-j] = matrix[i][n-1-j],matrix[i][j]
}
}
}

240. 搜索二维矩阵 II

搜索二维矩阵 II

二分查找

没用过sort.SearchInts() 原来是标准的二分

func searchMatrix(matrix [][]int, target int) bool {
for _, row := range matrix {
i := sort.SearchInts(row, target)
if i < len(row) && row[i] == target {
return true
}
}
return false
}

z字查找

matrix[x][y]一路走

func searchMatrix(matrix [][]int, target int) bool {
m, n := len(matrix), len(matrix[0])
x, y := 0, n-1
for x < m && y >= 0 {
if matrix[x][y] == target {
return true
}
if matrix[x][y] > target {
y--
} else {
x++
}
}
return false
}

链表

160. 相交链表

相交链表

双指针 相交

func getIntersectionNode(headA, headB *ListNode) *ListNode {
if headA == nil || headB == nil {
return nil
}
pa, pb := headA, headB
for pa != pb {
if pa == nil {
pa = headB
} else {
pa = pa.Next
}
if pb == nil {
pb = headA
} else {
pb = pb.Next
}
}
return pa
}

206. 反转链表

反转链表

维护 cur & pre

func reverseList(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
}
var pre *ListNode
cur,next := head, head.Next
for cur != nil {
next = cur.Next
cur.Next = pre
pre = cur
cur = next
}
return pre
}

234. 回文链表

回文链表

遍历后转数组

func isPalindrome(head *ListNode) bool {
vals := []int{}
for ; head != nil; head = head.Next {
vals = append(vals, head.Val)
}
n := len(vals)
for i, v := range vals[:n/2] {
if v != vals[n-1-i] {
return false
}
}
return true
}

中部反转 快慢指针

看得懂也不想写

func isPalindrome(head *ListNode) bool {
if head == nil && head.Next == nil {
return true
}
slow, fast := head, head
for fast.Next != nil && fast.Next.Next != nil {
slow = slow.Next
fast = fast.Next.Next
}
var prev *ListNode
cur := slow.Next
for cur != nil {
next := cur.Next
cur.Next = prev
prev = cur
cur = next
}
p1, p2 := prev, head
for p1 != nil && p2 != nil {
if p1.Val != p2.Val {
return false
}
p1 = p1.Next
p2 = p2.Next
}
return true
}

141. 环形链表

环形链表

快慢指针

func hasCycle(head *ListNode) bool {
slow, fast := head, head
for fast != nil && fast.Next != nil {
slow = slow.Next
fast = fast.Next.Next
if slow == fast {
return true
}
}
return false
}

142. 环形链表 II

环形链表 II

数学题目

func detectCycle(head *ListNode) *ListNode {
slow, fast := head, head
for fast != nil {
slow = slow.Next
if fast.Next == nil {
return nil
}
fast = fast.Next.Next
if fast == slow {
p := head
for p != slow {
p = p.Next
slow = slow.Next
}
return p
}
}
return nil
}

21. 合并两个有序链表

合并两个有序链表

dummy 按顺序添加

func mergeTwoLists(list1 *ListNode, list2 *ListNode) *ListNode {
dummy := ListNode{}
cur := &dummy
for list1 != nil && list2 != nil {
if list1.Val <= list2.Val {
cur.Next = list1
list1 = list1.Next
} else {
cur.Next = list2
list2 = list2.Next
}
cur = cur.Next
}
if list1 != nil {
cur.Next = list1
} else {
cur.Next = list2
}
return dummy.Next
}

2. 两数相加

两数相加

比较丑但是过题

func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
dummy := ListNode{}
cur := &dummy
curSum := 0
curVal := 0
carry := 0
for l1 != nil && l2 != nil {
curSum = l1.Val + l2.Val + carry
carry = curSum / 10
curVal = curSum % 10
cur.Next = &ListNode{
Val: curVal,
Next: nil,
}
cur = cur.Next
l1 = l1.Next
l2 = l2.Next
}
if l1 != nil {
for l1 != nil {
curSum = l1.Val + carry
carry = curSum / 10
curVal = curSum % 10
cur.Next = &ListNode{
Val: curVal,
Next: nil,
}
cur = cur.Next
l1 = l1.Next
}
} else {
for l2 != nil {
curSum = l2.Val + carry
carry = curSum / 10
curVal = curSum % 10
cur.Next = &ListNode{
Val: curVal,
Next: nil,
}
cur = cur.Next
l2 = l2.Next
}
}
if carry != 0 {
cur.Next = &ListNode{
Val: carry,
Next: nil,
}
}
return dummy.Next
}

优化版

把三个逻辑合并在一起使用

func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
dummy := &ListNode{}
cur := dummy
carry := 0
for l1 != nil || l2 != nil || carry != 0 {
sum := carry
if l1 != nil {
sum += l1.Val
l1 = l1.Next
}
if l2 != nil {
sum += l2.Val
l2 = l2.Next
}
cur.Next = &ListNode{Val: sum % 10}
cur = cur.Next
carry = sum / 10
}
return dummy.Next
}

19. 删除链表的倒数第 N 个结点

删除链表的倒数第 N 个结点

遍历后直接找节点

func removeNthFromEnd(head *ListNode, n int) *ListNode {
length := getLength(head)
dummy := &ListNode{Next: head}
cur := dummy
for i := 0; i < length-n; i++ {
cur = cur.Next
}
cur.Next = cur.Next.Next
return dummy.Next
}
func getLength(head *ListNode) (length int) {
for ; head != nil; head = head.Next {
length++
}
return
}

间隔为n的双指针

func removeNthFromEnd(head *ListNode, n int) *ListNode {
dummy := &ListNode{0, head}
first, second := head, dummy
for i := 0; i < n; i++ {
first = first.Next
}
for ; first != nil; first = first.Next {
second = second.Next
}
second.Next = second.Next.Next
return dummy.Next
}

24. 两两交换链表中的节点

两两交换链表中的节点

递归

func swapPairs(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
}
newHead := head.Next
head.Next = swapPairs(newHead.Next)
newHead.Next = head
return newHead
}

迭代

func swapPairs(head *ListNode) *ListNode {
dummy := &ListNode{Next: head}
cur := dummy
for cur.Next != nil && cur.Next.Next != nil {
node1 := cur.Next
node2 := cur.Next.Next
node1.Next = node2.Next
node2.Next = node1
cur.Next = node2
cur = node1
}
return dummy.Next
}

25. K 个一组翻转链表

K 个一组翻转链表

我讨厌你

分步做

func reverseKGroup(head *ListNode, k int) *ListNode {
dummy := &ListNode{Next: head}
pre := dummy
end := dummy
for end.Next != nil {
for i := 0; i < k && end != nil; i++ {
end = end.Next
}
if end == nil {
break
}
start := pre.Next
next := end.Next
end.Next = nil
pre.Next = reverse(start)
start.Next = next
pre = start
end = pre
}
return dummy.Next
}
func reverse(head *ListNode) *ListNode {
var pre *ListNode = nil
curr := head
for curr != nil {
next := curr.Next
curr.Next = pre
pre = curr
curr = next
}
return pre
}

138. 随机链表的复制

随机链表的复制

回溯+哈希表

func copyRandomList(head *Node) *Node {
cachedNode = map[*Node]*Node{}
return deepCopy(head)
}
var cachedNode map[*Node]*Node
func deepCopy(node *Node) *Node {
if node == nil {
return nil
}
if n, has := cachedNode[node];has {
return n
}
newNode := &Node{Val: node.Val}
cachedNode[node] = newNode
newNode.Next = deepCopy(node.Next)
newNode.Random = deepCopy(node.Random)
return newNode
}

A-A’-B-B’-C-C’

func copyRandomList(head *Node) *Node {
if head == nil {
return nil
}
for node := head; node != nil; node = node.Next.Next {
node.Next = &Node{Val: node.Val, Next: node.Next}
}
for node := head; node != nil; node = node.Next.Next {
if node.Random != nil {
node.Next.Random = node.Random.Next
}
}
headNew := head.Next
for node := head; node != nil; node = node.Next {
nodeNew := node.Next
node.Next = node.Next.Next
if nodeNew.Next != nil {
nodeNew.Next = nodeNew.Next.Next
}
}
return headNew
}

148. 排序链表

排序链表

归并

func sortList(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
}
slow, fast := head, head.Next
for fast != nil && fast.Next != nil {
slow = slow.Next
fast = fast.Next.Next
}
mid := slow.Next
slow.Next = nil
left := sortList(head)
right := sortList(mid)
return merge(left, right)
}
func merge(l1 *ListNode, l2 *ListNode) *ListNode {
dummy := &ListNode{}
cur := dummy
for l1 != nil && l2 != nil {
if l1.Val < l2.Val {
cur.Next = l1
l1 = l1.Next
} else {
cur.Next = l2
l2 = l2.Next
}
cur = cur.Next
}
if l1 != nil {
cur.Next = l1
}
if l2 != nil {
cur.Next = l2
}
return dummy.Next
}

More Posts