Skip to content

Ailoc/algorithm_base

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 

Repository files navigation

📋这是一个记录自己偶尔算法练习的代码仓库,有时间练一练,开发一下大脑

🧠 LeetCode Algorithm Notes

本项目用于整理和记录我的 LeetCode 刷题代码与思路,按照数据结构算法类型分类展示。
点击表格中的题目可以直接跳转到该题的详细代码实现。

1️⃣ 2️⃣ 3️⃣ 4️⃣ 5️⃣ 6️⃣ 7️⃣ 8️⃣ 9️⃣ 🔟

📘 数组 (Array)

# 题目 类型 LeetCode 难度
1 两数之和 哈希表 1. 两数之和 - 力扣(LeetCode) 🟢 Easy
2 最长公共前缀 动态规划 14. 最长公共前缀 - 力扣(LeetCode) 🟢 Easy
3 三数之和 动态规划 LCR 007. 三数之和 - 力扣(LeetCode) 🟢 Easy

🔗 链表 (LinkedList)

# 题目 类型 LeetCode 难度
1 反转链表 链表 206. 反转链表 - 力扣(LeetCode) 🟢 Easy
2 两两交换链表中的节点 链表 24. 两两交换链表中的节点 - 力扣(LeetCode) 🟢 Easy
3 环形链表 链表 141. 环形链表 - 力扣(LeetCode) 🟢 Easy
4 环形链表-找入环点 链表 142. 环形链表 II - 力扣(LeetCode)- 找入环点 🟢 Easy
5 K个一组翻转链表 链表 25. K 个一组翻转链表 - 力扣(LeetCode) 🟢 Easy

🧱 栈和队列 (Stack & Queue)

# 题目 类型 LeetCode 难度
1 有效的括号 20. 有效的括号 - 力扣(LeetCode) 🟢 Easy
2 用栈实现队列 232. 用栈实现队列 - 力扣(LeetCode) 🟢 Easy
3 用队列实现栈 225. 用队列实现栈 - 力扣(LeetCode) 🟢 Easy
4 股票价格跨度 单调栈 901. 股票价格跨度 - 力扣(LeetCode) 🟢 Easy

🧮 优先队列 (Priority Queue)

# 题目 类型 LeetCode 难度
1 数据流中的第K大元素 703. 数据流中的第 K 大元素 - 力扣(LeetCode) 🟢 Easy
2 滑动窗口最大值 队列 239. 滑动窗口最大值 - 力扣(LeetCode) 🟢 Easy
3 早餐组合 队列 LCP 18. 早餐组合 - 力扣(LeetCode) 🟢 Easy

🌳 二叉树 (Binary Tree)

# 题目 类型 LeetCode 难度
1 相同的树 二叉树 100. 相同的树 - 力扣(LeetCode) 🟢 Easy
2 验证二叉搜索树 二叉树 98. 验证二叉搜索树 - 力扣(LeetCode) 🟢 Easy
3 二叉树的最近公共祖先 二叉树 236. 二叉树的最近公共祖先 - 力扣(LeetCode) 🟢 Easy
4 二叉树的最近公共祖先 二叉树 235. 二叉搜索树的最近公共祖先 - 力扣(LeetCode) 🟢 Easy
5 二叉树的中序遍历 二叉树,递归 94. 二叉树的中序遍历 - 力扣(LeetCode) 🟢 Easy
6 对称二叉树 二叉树,递归 101. 对称二叉树 - 力扣(LeetCode) 🟢 Easy
7 二叉树的层序遍历 二叉树,队列 102. 二叉树的层序遍历 - 力扣(LeetCode) 🟢 Easy
8 二叉树的最小深度 二叉树,bfs,dfs 111. 二叉树的最小深度 - 力扣(LeetCode) 🟢 Easy
9 二叉树的最大深度 二叉树,bfs,dfs 104. 二叉树的最大深度 - 力扣(LeetCode) 🟢 Easy

🔢 哈希表与集合 (Map & Set)

# 题目 类型 LeetCode 难度
1 有效的字母异位词 哈希表 242. 有效的字母异位词 - 力扣(LeetCode) 🟢 Easy
2 多数元素 哈希表 169. 多数元素 - 力扣(LeetCode) 🟢 Easy

🌠 递归与分治 (Recursion & Divide&Conquer)

# 题目 类型 LeetCode 难度
1 x的n次方 分治 50. Pow(x, n) - 力扣(LeetCode) 🟢 Easy
2 括号生成 递归 22. 括号生成 - 力扣(LeetCode) 🟢 Easy

🗾 贪心算法 (Greedy)

在进行问题求解的时候,只做当前最优的选择。适用场景:问题能够被分为子问题来求解,并且子问题的最优解能够递推到最终问题的最优解。

# 题目 类型 LeetCode 难度
1 买卖股票的最佳时机 II 贪心 122. 买卖股票的最佳时机 II - 力扣(LeetCode) 🟢 Easy

⚽ 其他 (Others)

# 题目 类型 LeetCode 难度
1 十进制整数的反码 抑或运算 1009. 十进制整数的反码 - 力扣(LeetCode) 🟢 Easy

1️⃣ 两数之和

func twoSum(nums []int, target int) []int {
    m := map[int]int{}
    for index1, v1 := range nums {
        if index2, ok := m[target - v1]; !ok {
            m[v1] = index1
        } else {
            return []int{index2, index1}
        }
    }
    return nil
}

2️⃣ 最长公共前缀

func longestCommonPrefix(strs []string) string {
    u := []rune{}
    flag := true
    for index, c := range strs[0] { 
        for i := 1; i < len(strs) && flag == true; i++ {
            if index < len(strs[i]) && rune(strs[i][index]) == c {
                flag = true
            } else {
                flag = false
                break
            }
        }
        if flag == true {
            u = append(u, c)
        }
    }
    return string(u)
}

3️⃣ 三数之和

image
func threeSum(nums []int) [][]int {
    sort.Ints(nums)
    var res [][]int
    n := len(nums)
    for i := 0; i < n-2; i++ {
        // 避免生成相同的target,去重
        if i > 0 && nums[i] == nums[i-1] {
            continue
        }
        target := -nums[i]
        tmp := make(map[int]bool)
        for j := i + 1; j < n; j++ {
            a := target - nums[j]
            if tmp[a] {     // a与map中的值可以相同
                res = append(res, []int{nums[i], a, nums[j]})
                for j+1 < n && nums[j] == nums[j+1] {
                    j++
                }
            }
            tmp[nums[j]] = true
        }
    }
    return res
}

1️⃣ 反转链表

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func reverseList(head *ListNode) *ListNode {
    prev := (*ListNode)(nil)
    cur := head
    for cur != nil {
        head = head.Next
        cur.Next = prev
        prev = cur
        cur = head
    }
    return prev
}

2️⃣ 两两交换链表中的节点

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func swapPairs(head *ListNode) *ListNode {
    if head == nil || head.Next == nil {
        return head
    }
    prevHead := &ListNode{0, head}
    cur, swapNode := head, head.Next
    rt := swapNode
    for {
        prevHead.Next = swapNode
        cur.Next = swapNode.Next
        swapNode.Next = cur
        prevHead = cur
        if cur.Next != nil && cur.Next.Next != nil {
            cur = cur.Next
            swapNode = cur.Next
        }else {
            break
        }
    }
    return rt
}

3️⃣ 环形链表

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func hasCycle(head *ListNode) bool {
    // fast, slow := head, head
    // for slow != nil && fast != nil && fast.Next != nil {
    //     slow = slow.Next
    //     fast = fast.Next.Next
    //     if slow == fast {
    //         return true
    //     }
    // }
    // return false

    m := map[*ListNode]struct{}{}
    cur := head
    for cur != nil {
        if _, ok := m[cur]; ok {
            return true
        }else {
            m[cur] = struct{}{}
        }
        cur = cur.Next
    }
    return false
}

4️⃣ 环形链表-找入环点

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func detectCycle(head *ListNode) *ListNode {
    // m := map[*ListNode]struct{}{}
    // for head != nil {
    //     if _, ok := m[head]; ok {
    //         return head
    //     }
    //     m[head] = struct{}{}
    //     head = head.Next
    // }
    // return nil

    fast, slow := head, head
    for fast != nil && fast.Next != nil{
        slow = slow.Next
        fast = fast.Next.Next
        if slow == fast {
            fast = head
            for slow != fast {
                fast = fast.Next
                slow = slow.Next
            }
            return slow
        }
    }
    return nil
}

5️⃣ K个一组翻转链表

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func reverseKGroup(head *ListNode, k int) *ListNode {
    if head == nil || head.Next == nil || k == 1 {
        return head
    }
    dummy := &ListNode{0, head}
    prevGroup := dummy
    for head != nil {
        curr := head
        count := 0
        for curr != nil && count < k {
            count++
            curr = curr.Next
        }
        if count < k {
            break
        }
        curr = head
        var prev *ListNode
        for i := 0; i < k; i++ {
            next := curr.Next
            curr.Next = prev
            prev = curr
            curr = next
        }
        prevGroup.Next = prev
        head.Next = curr
        prevGroup = head
        head = curr
    }
    return dummy.Next
}

1️⃣ 有效的括号

func isValid(s string) bool {
    stack := []rune{}
    for _, ch := range s{
        switch ch {
        case '(', '{', '[':
            stack = append(stack, ch)
        case ')', '}', ']':
            if len(stack) > 0 {
                if (ch == ')' && stack[len(stack)-1] == '(') ||
                (ch == '}' && stack[len(stack)-1] == '{') ||
                (ch == ']' && stack[len(stack)-1] == '[') {
                    stack = stack[:len(stack)-1]
                }else {
                    return false
                }
            }else {
                return false
            }
        }
    }
    return len(stack) == 0
}

2️⃣ 用栈实现队列

type MyQueue struct {
    stack1 []int
    stack2 []int
}


func Constructor() MyQueue {
    return MyQueue{}
}


func (this *MyQueue) Push(x int)  {
    for len(this.stack2) > 0 {
        this.stack1 = append(this.stack1, this.stack2[len(this.stack2)-1])
        this.stack2 = this.stack2[:len(this.stack2)-1]
    }
    this.stack1 = append(this.stack1, x)
}


func (this *MyQueue) Pop() int {
    if len(this.stack2) > 0 {
        res := this.stack2[len(this.stack2)-1]
        this.stack2 = this.stack2[:len(this.stack2)-1]
        return res
    }
    for len(this.stack1) > 0 {
        this.stack2 = append(this.stack2, this.stack1[len(this.stack1)-1])
        this.stack1 = this.stack1[:len(this.stack1)-1]
    }
    res := this.stack2[len(this.stack2)-1]
    this.stack2 = this.stack2[:len(this.stack2)-1]
    return res
}


func (this *MyQueue) Peek() int {
    if len(this.stack2) > 0 {
        return this.stack2[len(this.stack2)-1]
    }
    for len(this.stack1) > 0 {
        this.stack2 = append(this.stack2, this.stack1[len(this.stack1)-1])
        this.stack1 = this.stack1[:len(this.stack1)-1]
    }
    return this.stack2[len(this.stack2)-1]
}


func (this *MyQueue) Empty() bool {
    return len(this.stack1) == 0 && len(this.stack2) == 0
}


/**
 * Your MyQueue object will be instantiated and called as such:
 * obj := Constructor();
 * obj.Push(x);
 * param_2 := obj.Pop();
 * param_3 := obj.Peek();
 * param_4 := obj.Empty();
 */

3️⃣ 用队列实现栈

type MyStack struct {
    queue1 []int
    queue2 []int
}


func Constructor() MyStack {
    return MyStack{}
}


func (this *MyStack) Push(x int)  {
    if len(this.queue2) > 0 {
        this.queue2 = append(this.queue2, x)
        return
    }
    this.queue1 = append(this.queue1, x)
}


func (this *MyStack) Pop() int {
    res := 0
    if len(this.queue1) > 0 {
        for len(this.queue1) > 1 {
            this.queue2 = append(this.queue2, this.queue1[0])
            this.queue1 = this.queue1[1:]
        }
        res = this.queue1[0]
        this.queue1 = this.queue1[0:0]
    } else {
        for len(this.queue2) > 1 {
            this.queue1 = append(this.queue1, this.queue2[0])
            this.queue2 = this.queue2[1:]
        }
        res = this.queue2[0]
        this.queue2 = this.queue2[0:0]
    }
    return res
}


func (this *MyStack) Top() int {
    res := 0
    if len(this.queue1) > 0 {
        for len(this.queue1) > 1 {
            this.queue2 = append(this.queue2, this.queue1[0])
            this.queue1 = this.queue1[1:]
        }
        res = this.queue1[0]
        this.queue1 = this.queue1[0:0]
        this.queue2 =  append(this.queue2, res)
    } else {
        for len(this.queue2) > 1 {
            this.queue1 = append(this.queue1, this.queue2[0])
            this.queue2 = this.queue2[1:]
        }
        res = this.queue2[0]
        this.queue2 = this.queue2[0:0]
        this.queue1 =  append(this.queue1, res)
    }
    return res
}


func (this *MyStack) Empty() bool {
    return len(this.queue1) == 0 && len(this.queue2) == 0
}


/**
 * Your MyStack object will be instantiated and called as such:
 * obj := Constructor();
 * obj.Push(x);
 * param_2 := obj.Pop();
 * param_3 := obj.Top();
 * param_4 := obj.Empty();
 */

1️⃣ 数据流中的第K大元素

type KthLargest struct {
    u sort.IntSlice
    k int
}


func Constructor(k int, nums []int) KthLargest {
    kl := KthLargest{
        u: sort.IntSlice(nums),
        k: k,
    }
    sort.Sort(sort.Reverse(kl.u))
    return kl
}


func (this *KthLargest) Add(val int) int {
    if len(this.u) >= this.k && this.u[this.k-1] >= val {
        return this.u[this.k-1]
    }
    this.u = append(this.u, val)
    sort.Sort(sort.Reverse(this.u))
    this.u = this.u[:this.k]
    return this.u[this.k-1]
}


/**
 * Your KthLargest object will be instantiated and called as such:
 * obj := Constructor(k, nums);
 * param_1 := obj.Add(val);
 */

2️⃣ 滑动窗口最大值

func maxSlidingWindow(nums []int, k int) []int {
    if len(nums) == 0 || k <= 0 || k > len(nums) {
        return []int{}
    }
    if k == 1 {
        return nums
    }
    
    // 使用双端队列存储索引
    deque := make([]int, 0, k)
    // 预分配结果切片容量
    res := make([]int, 0, len(nums)-k+1)
    
    for i := 0; i < len(nums); i++ {
        // 移除窗口外的索引
        if len(deque) > 0 && deque[0] <= i-k {
            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 {
            res = append(res, nums[deque[0]])
        }
    }
    return res
}

3️⃣ 早餐组合

func breakfastNumber(staple []int, drinks []int, x int) int {
    num := 0
    sort.Ints(staple)
    sort.Ints(drinks)
    for _, s := range staple {
        target := x - s 
        low := 0
        high := len(drinks)-1
        for low <= high {
            mid := (low + high) / 2
            if drinks[mid] > target {
                high = mid - 1
            }else {
                low = mid + 1
            }
        }
        num += low
    }
    return num % 1000000007
}

1️⃣ 相同的树

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func isSameTree(p *TreeNode, q *TreeNode) bool {
    if p == nil && q == nil{return true}
    if (p == nil && q != nil) || (p != nil && q == nil) || p.Val != q.Val {return false}
    if p.Val == q.Val {
        return isSameTree(p.Left, q.Left) && isSameTree(p.Right, q.Right)
    }
    return false
}

2️⃣ 验证二叉搜索树

image
/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func isValidBST(root *TreeNode) bool {
    prev := new(int)  // 分配内存
    *prev = math.MinInt64  // 初始化为负无穷哨兵
    return inorder(root, prev)
}

func inorder(node *TreeNode, prev *int) bool {
    if node == nil {
        return true
    }
    // 先递归左子树
    if !inorder(node.Left, prev) {
        return false
    }
    // 访问当前节点:检查递增性
    if node.Val <= *prev {
        return false
    }
    *prev = node.Val  // 更新前驱
    // 后递归右子树
    if !inorder(node.Right, prev) {
        return false
    }
    return true
}

3️⃣ 二叉树的最近公共祖先

image
/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
  if root == nil || root == p || root == q {return root}
  left := lowestCommonAncestor(root.Left, p, q)
  right := lowestCommonAncestor(root.Right, p, q)
  if left != nil && right != nil{
    return root
  }
  if right == nil{
    return left
  }
  return right
}

1️⃣ 有效的字母异位词

image
func isAnagram(s string, t string) bool {
    if len(s) != len(t) {return false}
    u := map[rune]int{}
    for i := 0; i < len(s); i++ {
        if _, ok := u[rune(s[i])]; ok {
            u[rune(s[i])]++
        } else {
            u[rune(s[i])] = 1
        }
        if _, ok := u[rune(t[i])]; ok {
            u[rune(t[i])]--
        } else {
            u[rune(t[i])] = -1
        }
    }
    for _, v := range u {
        if v != 0 {return false}
    }
    return true
}

4️⃣ 二叉搜索树的最近公共祖先

image
/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val   int
 *     Left  *TreeNode
 *     Right *TreeNode
 * }
 */

func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
    // 递归终止条件
    if root == nil {return nil}
	// 如果都在右子树
	if p.Val > root.Val && q.Val > root.Val {
        return lowestCommonAncestor(root.Right, p, q)
    }
	// 如果都在左子树
    if p.Val < root.Val && q.Val < root.Val {
        return lowestCommonAncestor(root.Left, p, q)
    }
    return root
}

4️⃣-股票价格跨度

image
type StockSpanner struct {
    stack []pair     // 单调栈,栈底价格至栈顶依此增大
}
type pair struct {
    price int
    span int
}

func Constructor() StockSpanner {
    return StockSpanner{}
}

func (this *StockSpanner) Next(price int) int {
    span := 1
    for len(this.stack) > 0 && this.stack[len(this.stack)-1].price <= price {
        // 如果当前栈顶price小于当前price,则当前span = 栈顶span + 1
        // 然后还需要继续向栈底判断,如果还有小于当前price的pair则需要再次加上相应的span
        span += this.stack[len(this.stack)-1].span
        // 不断删除栈顶小于当前价格的pair
        this.stack = this.stack[:len(this.stack)-1]
    }
    // 目前栈顶span价格大于当前price,则构造pair并加入栈顶
    this.stack = append(this.stack, pair{price: price, span: span})
    return span
}
/**
 * Your StockSpanner object will be instantiated and called as such:
 * obj := Constructor();
 * param_1 := obj.Next(price);
 */

5️⃣ 二叉树的中序遍历

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func inorderTraversal(root *TreeNode) []int {
    arr := make([]int, 0)
    Inorder(root, &arr)
    return arr
}
// 得传入切片指针
func Inorder(root *TreeNode, arr *[]int) {
    if root == nil {
        return 
    }
    Inorder(root.Left, arr)
    *arr = append(*arr, root.Val)
    Inorder(root.Right, arr)
}

6️⃣ 对称二叉树

image
/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func isSymmetric(root *TreeNode) bool {
    if root == nil {
        return true
    }
    return compare(root.Left, root.Right)
}

func compare(left, right *TreeNode) bool {
    // 处理空节点:一空一非 false,两空 true
    if left == nil || right == nil {
        return left == right
    }
    // 值不相等:不对称
    if left.Val != right.Val {
        return false
    }
    // 镜像递归:外侧 (left.Left ↔ right.Right),内侧 (left.Right ↔ right.Left)
    return compare(left.Left, right.Right) && compare(left.Right, right.Left)
}

1️⃣ x的n次方

func myPow(x float64, n int) float64 {
    if n < 0 {
        x = 1 / x
        n = -n
    }
    if n == 0 {return 1}
    if n == 1 {return x}
    half := myPow(x, n / 2)
    if n % 2 == 0 {
        return half * half
    } else {
        return half * half * x
    }
}

2️⃣ 多数元素

image
func majorityElement(nums []int) int {
    if len(nums) == 1 {return nums[0]}
    res := make(map[int]int)
    for _, value := range nums {
        if v, ok := res[value]; ok {
            res[value] = v + 1
            if res[value] > (len(nums) / 2) {
                return value
            }
        } else {
            res[value] = 1
        }
    }
    return 0
}

1️⃣ 买卖股票的最佳时机 II

image
func maxProfit(prices []int) int {
    if len(prices) == 0 || len(prices) == 1 {return 0}
    yesterday := prices[0]
    res := 0
    for i := 1; i < len(prices); i++ {
        if yesterday < prices[i] {
            res += (prices[i] - yesterday)
        }
        yesterday = prices[i]
    }
    return res
}

7️⃣ 二叉树的层序遍历

image
/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func levelOrder(root *TreeNode) [][]int {
    if root == nil {
        return [][]int{}
    }
    queue := []*TreeNode{root}  // 简化为字面量初始化
    res := [][]int{}
    for len(queue) > 0 {
        levelSize := len(queue)  // 当前层节点数(有效节点)
        levelVals := []int{}     // 当前层值
        for i := 0; i < levelSize; i++ {
            node := queue[0]
            queue = queue[1:]
            levelVals = append(levelVals, node.Val)  // 假设无 nil 节点(标准树)
            // 只追加非 nil 子节点
            if node.Left != nil {
                queue = append(queue, node.Left)
            }
            if node.Right != nil {
                queue = append(queue, node.Right)
            }
        }
        res = append(res, levelVals)
    }
    return res
}

8️⃣ 二叉树的最小深度

image
/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func minDepth(root *TreeNode) int {
    // if root == nil {
    //     return 0
    // }
    // // 一旦根节点有子节点,那么根节点就不可能是叶子节点
    // if root.Left == nil {
    //     return 1 + minDepth(root.Right)
    // }
    // if root.Right == nil {
    //     return 1 + minDepth(root.Left)
    // }
    // left := 1 + minDepth(root.Left)
    // right := 1 + minDepth(root.Right)
    // if left < right {
    //     return left
    // }
    // return right
    return bfs(root)
}
func bfs(root *TreeNode) int {
    if root == nil {return 0}
    nodeQueue := []*TreeNode{root}
    deep := 0
    for len(nodeQueue) > 0 {
        levelSize := len(nodeQueue)
        for i := 0; i < levelSize; i++ {
            if nodeQueue[i].Left == nil && nodeQueue[i].Right == nil {return deep+1}
            if nodeQueue[i].Left != nil {
                nodeQueue = append(nodeQueue, nodeQueue[i].Left)
            }
            if nodeQueue[i].Right != nil {
                nodeQueue = append(nodeQueue, nodeQueue[i].Right)
            }
        }
        nodeQueue = nodeQueue[levelSize:]
        deep += 1
    }
    return deep
}

9️⃣ 二叉树的最大深度

image
/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func maxDepth(root *TreeNode) int {
    // if root == nil {return 0}
    // left := maxDepth(root.Left) + 1
    // right := maxDepth(root.Right) + 1
    // if left > right {
    //     return left
    // }
    // return right
    return bfs(root)
}
func bfs(root *TreeNode) int {
    if root == nil {return 0}
    queue := []*TreeNode{root}
    deep := 0
    for len(queue) > 0 {
        levelSize := len(queue)
        for i := 0; i < levelSize; i++ {
            if queue[i].Left != nil {
                queue = append(queue, queue[i].Left)
            }
            if queue[i].Right != nil {
                queue = append(queue, queue[i].Right)
            }
        }
        deep += 1
        queue = queue[levelSize:]
    }
    return deep
}

1️⃣ 十进制整数的反码

image
func bitwiseComplement(n int) int {
    if n == 0 {
        return 1
    }
    tmp, bit := n, 1
    for tmp != 0 {
        n = bit ^ n
        bit = bit << 1
        tmp = tmp >> 1   //用于判断整个数是否已经处理结束,结束时tmp为0
    }
    return n
}

2️⃣ 括号生成

image
func generateParenthesis(n int) []string {
    res := make([]string, 0)
    gen("", &res, n, n)
    return res
}
//按照括号匹配规范生成括号串
func gen(s string, res *[]string, left, right int) {
    if left == 0 && right == 0 {
        *res = append(*res, s)
        return 
    }
    // 左括号只要有就可以加进去
    if left > 0 {
        gen(s+"(", res, left-1, right)
    }
    // 右括号必须在左括号数大于右括号数时才可以添加
    if right > left {
        gen(s+")", res, left, right-1)
    }
}

About

这是一个记录自己偶尔算法练习的代码仓库

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published