第一周 数组、链表、栈、队列

2021-11-25
10分钟阅读时长

题目数:19

本周作业

Facebook字节跳动微软Amazon快手美团Google腾讯华为百度
0033004000
// 写法一,面试推荐写法
func plusOne(digits []int) []int {
    n := len(digits)
    for i := n - 1; i >=0; i-- {
        digits[i] = (digits[i] + 1) % 10
        if digits[i] != 0 {
            return digits
        }
    }
    ans := make([]int, n + 1)
    ans[0] = 1
    return ans
}

// 写法二:
func plusOne(digits []int) []int {
    for i := len(digits) - 1; i >= 0; i-- {
        // 统计9的个数
        if digits[i] != 9 {
            digits[i]++
            for j := i + 1; j < len(digits); j++ {
                digits[j] = 0
            }
            return digits
        }
    }
    digits = make([]int, len(digits) + 1)
    digits[0] = 1
    return digits
}
Facebook字节跳动微软Amazon快手美团Google腾讯华为百度
7239362221403
/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
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, cur = list1.Next, cur.Next
        } else {
            cur.Next = list2
            list2, cur = list2.Next, cur.Next
        }
    }
    if list1 != nil {
        cur.Next = list1
    } else {
        cur.Next = list2
    }
    return dummy.Next
}
Facebook字节跳动微软Amazon快手美团Google腾讯华为百度
2000000000

华为字节跳动GoogleAmazonApple
38544

实战例题

以下为课上实战例题

第 1 课 数组、链表

数组

(Easy)半年内出题频次:

Facebook字节跳动微软Amazon快手美团Google腾讯华为百度
3319116553033
func merge(nums1 []int, m int, nums2 []int, n int) {
    last := m + n - 1
    for m, n = m - 1, n - 1; m >= 0 && n >= 0; last = last - 1 {
        if nums1[m] < nums2[n] {
            nums1[last], n = nums2[n], n - 1
        } else {
            nums1[last], m = nums2[m], m - 1
        }
    }
    for n >= 0 {
        nums1[last], last, n = nums2[n], last - 1, n - 1
    }
}

(Easy)半年内出题频次:

Facebook字节跳动微软Amazon滴滴美团GoogleApple
1113662224
// 写法一
func removeDuplicates(nums []int) int {
    idx := 0
    for cur, n := 0, len(nums); cur < n; cur++ {
        if cur == 0 || nums[cur-1] != nums[cur] {
            nums[idx] = nums[cur]
            idx++
        }
    }
    return idx
}

// 写法二
func removeDuplicates(nums []int) int {
    n := len(nums)
    if n == 0 {
        return 0
    }
    slow := 1
    for fast := 1; fast < n; fast++ {
        if nums[fast] != nums[fast-1] {
            nums[slow] = nums[fast]
            slow++
        }
    }
    return slow
}

(Easy)半年内出题频次:

Facebook字节跳动微软AmazonBloombergAppleGoogleeBayCiscoSAP思爱普
19987755332
// 写法一
func moveZeroes(nums []int)  {
    n := len(nums)
    for lastNonZero, i := 0, 0; i < n; i++ {
        if nums[i] != 0 {
            nums[lastNonZero], nums[i] = nums[i], nums[lastNonZero]
            lastNonZero++
        }
    }
}

// 写法二
func moveZeroes(nums []int)  {
    lastNonZero, n := 0, len(nums)
    for i := 0; i < n; i++ {
        if nums[i] != 0 {
            nums[lastNonZero] = nums[i]
            lastNonZero++
        }
    }
    for lastNonZero < n {
        nums[lastNonZero] = 0
        lastNonZero++
    }
}

链表

(Easy)半年内出题频次:

Facebook字节跳动微软Amazon滴滴美团Google腾讯Apple百度
4429137761474
/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
// 迭代
func reverseList(head *ListNode) *ListNode {
    var pre *ListNode
    for head != nil {
        // tmp := head.Next
        // head.Next = pre
        // pre = head
        // head = tmp
        pre, head, head.Next = head, head.Next, pre
    }
    return pre
}

// 递归
func reverseList(head *ListNode) *ListNode {
    if head == nil || head.Next == nil {
        return head
    }
    newHead := reverseList(head.Next)
    head.Next.Next = head
    head.Next = nil
    return newHead
}

// 头插法
func reverseList(head *ListNode) *ListNode {
    dummy := new(ListNode)
    for head != nil {
        head.Next, dummy.Next, head = dummy.Next, head, head.Next
    }
    return dummy.Next
}

(Hard)半年内出题频次:

Facebook字节跳动微软Amazon快手美团Google腾讯AppleeBay
5401315223633
/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
// 方法一: 迭代 + 尾插法
func reverseKGroup(head *ListNode, k int) *ListNode {
    dummy := &ListNode{}
    dummy.Next = head
    pre, tail := dummy, dummy
    for pre.Next != nil {
        for i := 0; i < k && tail != nil; i++ {
            tail = tail.Next
        }
        if tail == nil {
            break
        }
        next := pre.Next
        for pre.Next != tail {
            cur := pre.Next
            pre.Next = cur.Next

            cur.Next = tail.Next
            tail.Next = cur
        }
        pre, tail = next, next
    }
    return dummy.Next
}

// 方法二:迭代 + 独立反转函数(递归、头插法、旧地反转)
func reverseKGroup(head *ListNode, k int) *ListNode {
    dummy := &ListNode{}
    dummy.Next = head
    pre, tail := dummy, dummy
    for pre.Next != nil {
        for i :=0; i < k &&tail != nil; i++ {
            tail = tail.Next
        }
        if tail == nil {
            break
        }
        next := tail.Next
        tail.Next = nil
        head =  pre.Next
        pre.Next = reverse(pre.Next)
        head.Next = next
        pre, tail = head, head
    }
    return dummy.Next
}

func reverse(head *ListNode) *ListNode {
    // 头插法
    dummy := &ListNode{}
    for head != nil {
        cur := head.Next
        head.Next = dummy.Next
        dummy.Next = head
        head = cur
    }
    return dummy.Next
}

// 方法三:递归 + 尾插法
func reverseKGroup(head *ListNode, k int) *ListNode {
    count, cur := 0, head
    for ; count < k && cur != nil; count++ {
        cur = cur.Next
    }
    if count == k {
        cur = reverseKGroup(cur, k)
        for ; count > 0; count-- {
            next := head.Next
            head.Next = cur
            cur = head
            head = next
        }
        head = cur
    }
    return head
}

(Medium)(ACWing)


(Medium)半年内出题频次:

Facebook字节跳动微软AmazonBloomberg百度腾讯AppleShopee
4117733322
/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
// 方法一:快慢指针
func hasCycle(head *ListNode) bool {
    slow, fast := head, head
    for fast != nil && fast.Next != nil {
        slow, fast = slow.Next, fast.Next.Next
        if slow == fast {
            return true
        }
    }
    return false
}

// 方法二:哈希表

(Medium)半年内出题频次:

Facebook字节跳动微软Amazon快手美团Google腾讯华为百度
21422020000
/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func detectCycle(head *ListNode) *ListNode {
    slow, fast := head, head
    for fast != nil && fast.Next != nil {
        slow, fast = slow.Next, fast.Next.Next
        if slow == fast {
            for slow != head {
                slow, head = slow.Next, head.Next
            }
            return slow
        }
    }
    return nil
}

第 2 课 栈、队列

(Medium)半年内出题频次:

Facebook字节跳动微软AmazonAppleGoogleBloomberg华为LinkedInShopee
1224152510798137
// 写法一:
func isValid(s string) bool {
    n := len(s)
    if n % 2 == 1 {
        return false
    }
    pairs := map[byte]byte{
        ')': '(',
        ']': '[',
        '}': '{',
    }
    stack := []byte{}
    for _, c := range []byte(s) {
        if pairs[c] > 0 {
            if len(stack) == 0 || stack[len(stack)-1] != pairs[c] {
                return false
            }
            stack = stack[:len(stack)-1]
        } else {
            stack = append(stack, c)
        }
    }
    return len(stack) == 0
}
// 写法二:
func isValid(s string) bool {
    n := len(s)
    if n % 2 == 1 {
        return false
    }
    pairs := map[byte]byte{
        ')': '(',
        ']': '[',
        '}': '{',
    }
    stack := []byte{}
    for i := 0; i < n; i++ { // 区别
        if pairs[s[i]] > 0 {
            if len(stack) == 0 || stack[len(stack)-1] != pairs[s[i]] {
                return false
            }
            stack = stack[:len(stack)-1]
        } else {
            stack = append(stack, s[i])
        }
    }
    return len(stack) == 0
}

(Medium)半年内出题频次:

Bloomberg字节跳动微软Amazon快手美团GoogleApple高盛集团Coupang
12101215000300
type MinStack struct {
    stack, minStack []int
}


func Constructor() MinStack {
    return MinStack{}
}


func (this *MinStack) Push(val int)  {
    this.stack = append(this.stack, val)
    minVal := val
    if len(this.minStack) > 0 && this.minStack[len(this.minStack)-1] < val {
        minVal = this.minStack[len(this.minStack)-1]
    }
    this.minStack = append(this.minStack, minVal)
}


func (this *MinStack) Pop()  {
    l := len(this.stack)
    this.stack = this.stack[:l-1]
    this.minStack = this.minStack[:l-1]
}


func (this *MinStack) Top() int {
    return this.stack[len(this.stack)-1]
}


func (this *MinStack) GetMin() int {
    return this.minStack[len(this.minStack)-1]
}


/**
 * Your MinStack object will be instantiated and called as such:
 * obj := Constructor();
 * obj.Push(val);
 * obj.Pop();
 * param_3 := obj.Top();
 * param_4 := obj.GetMin();
 */

(Medium)半年内出题频次:

Facebook字节跳动微软AmazonLinkedInGoogle
333866

(Hard)半年内出题频次:

Facebook字节跳动微软AmazonRobloxShopeeGoogleAppleWish
81512763422

单调栈、单调队列

(Hard)半年内出题频次:

字节跳动微软AmazoneBayGoogle华为
759232
// 写法一:
func largestRectangleArea(heights []int) (ans int) {
    // 比栈顶元素小大才出栈,最后一个元素后需要补一个0,让最后一个元素有机会出栈。
    heights = append(heights, 0)
    // 单调升序栈
    stack := []int{}
    for i, height := range heights {
        for len(stack) > 0 && height < heights[stack[len(stack)-1]] {
            top := stack[len(stack)-1]
            stack = stack[:len(stack)-1]
            width := i
            if len(stack) > 0 {
                width = i - stack[len(stack)-1] - 1
            }
            ans = max(ans,  heights[top] * w)
        }
        stack = append(stack, i)
    }
    return ans
}
// 写法二:
func largestRectangleArea(heights []int) (maxArea int) {
    stack := []int{}
    stack = append(stack, -1)
    for i, height := range heights {
        // 从小 -> 大 栈
        for stack[len(stack) - 1] != -1 && height < heights[stack[len(stack) - 1]]{
            top := stack[len(stack) - 1]
            stack = stack[:len(stack) - 1]
            h := heights[top]
            maxArea = max(maxArea, h * (i - stack[len(stack) - 1] - 1))
        }
        stack = append(stack, i)
    }
    last := len(heights)
    // 处理剩余数据
    for stack[len(stack) - 1] != -1 {
        top := stack[len(stack) - 1]
        stack = stack[:len(stack) - 1]
        h := heights[top]
        maxArea = max(maxArea, h * (last - stack[len(stack) - 1] - 1))
    }
    return maxArea
}

func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}

(Hard)半年内出题频次:

Facebook字节跳动微软Amazon高盛集团Google阿里巴巴BloombergTwitter
6652728222
// 方法一:双端队列

// 方法二:大顶堆

(Hard)半年内出题频次:

Facebook字节跳动微软Amazon高盛集团美团GoogleBloomberg网易Apple
3534946345101175
// 方法一:单调栈(大->小)
func trap(heights []int) (ans int) {
    stack := []int{}
    for i, height := range heights {
        for len(stack) > 0 && height > heights[stack[len(stack)-1]]{
            top := stack[len(stack)-1]
            stack = stack[:len(stack)-1]
            if len(stack) == 0 {
                break
            }
            ans += ((min(height, heights[stack[len(stack)-1]]) - heights[top]) * (i - stack[len(stack)-1] - 1))
        }
        stack = append(stack, i)
    }
    return ans
}
// 方法二:双指针
func trap(height []int) (ans int) {
    left, right := 0, len(height) - 1
    leftMax, rightMax := 0, 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
}

// 公共函数
func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}

func min(a, b int) int {
    if a < b {
        return a
    }
    return b
}