leetcode热题100记录

74 阅读14分钟

哈希

1.两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。

class Solution {
        func twoSum(_ nums: [Int], _ target: Int) -> [Int] {
            var dic: [Int: Int] = [:]
            for (index, value) in nums.enumerated() {
                let dif = target - value
                if dic[dif] != nil {
                    // 找到了
                    return [dic[dif]!, index]
                } else {
                    dic[value] = index
                }
            }
            return []
        }
}

2.字母异位词分组

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。

字母异位词 是由重新排列源单词的所有字母得到的一个新单词。

class Solution {
        func groupAnagrams(_ strs: [String]) -> [[String]] {
            var dic: [String: [String]] = [:]
            for str in strs {
                let key = String(str.sorted())
                if dic[key] != nil {
                    dic[key]!.append(str)
                } else {
                    dic[key] = [str]
                }
            }
            var result = [[String]]()
            for value in dic {
                result.append(value.value)
            }
            return result
        }
}

3.最长连续序列

给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。

请你设计并实现时间复杂度为 O(n) **的算法解决此问题。

class Solution {
        func longestConsecutive(_ nums: [Int]) -> Int {
            var maxLength = 0
            var set = Set<Int>()
            for value in nums {
                set.insert(value)
            }
            
            for value in set {
                if (!set.contains(value - 1)) {
                    var current = 1
                    var value = value
                    while set.contains(value + 1) {
                        current += 1
                        value += 1
                    }
                    maxLength = max(maxLength, current)
                }
            }
            return maxLength
        }
}

双指针

1.移动零

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

请注意 ,必须在不复制数组的情况下原地对数组进行操作。

    class Solution {
        // 双指针解法
        func moveZeroes(_ nums: inout [Int]) {
            var left = 0
            var right = 0
            while left < nums.count && right < nums.count {
                if (nums[right] != 0) {
                    nums.swapAt(left, right)
                    left += 1
                    right += 1
                } else {
                    right += 1
                }
            }
        }
    }

2.盛最多水的容器

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。

说明: 你不能倾斜容器。

class Solution {
        func maxArea(_ height: [Int]) -> Int {
            let length = height.count
            var left = 0
            var right = length - 1
            
            var maxWater = 0
            
            while left <= right {
                let length = right - left
                let waterHeight = min(height[left], height[right])
                let currentWater = waterHeight * length
                maxWater = max(maxWater, currentWater)
                if (height[left] <= height[right]) {
                    left += 1
                } else {
                    right -= 1
                }
            }
            return maxWater
        }
}

3. 三数之和

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。

注意: 答案中不可以包含重复的三元组。

class Solution {
        func threeSum(_ nums: [Int]) -> [[Int]] {
            var result = [[Int]]()
            var set = Set<Set<Int>>()
            for (index, value) in nums.enumerated() {
                let target = -value
                var dic = [Int: Int]()
                for i in (index + 1)..<nums.count {
                        let dif = target - nums[i]
                        if dic[dif] != nil {
                            let currentResult = [-target, dif, dic[dif]!]
                            let resultSet = Set(currentResult)
                            if !set.contains(resultSet) {
                                set.insert(resultSet)
                                result.append(currentResult)
                            }
                        } else {
                            dic[nums[i]] = dif
                        }
                }
            }
            
            return result
        }
}

滑动窗口

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

给定一个字符串 s ,请你找出其中不含有重复字符的 最长 子串 的长度

class Solution {
        func lengthOfLongestSubstring(_ s: String) -> Int {
            let array = s.map { String($0) }
            var maxLength = 0
            var subString = Array<String>()
            for value in array {
                    if let index = subString.firstIndex(where: { string in
                        string == value
                    }) {
                        subString.removeFirst(index + 1)
                    }
                    subString.append(value)
                maxLength = max(maxLength, subString.count)
            }
            return maxLength
        }
}

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

给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。

class Solution {
        func findAnagrams(_ s: String, _ p: String) -> [Int] {
            var result = [Int]()
            var sArray = Array(repeating: 0, count: 26)
            var pArray = Array(repeating: 0, count: 26)
            let sCount = s.count
            let pCount = p.count
            if sCount < pCount {
                return []
            }
            for i in 0..<pCount {
                sArray[Int(s[s.index(s.startIndex, offsetBy: i)].asciiValue! - Character("a").asciiValue!)] += 1
                pArray[Int(p[p.index(p.startIndex, offsetBy: i)].asciiValue! - Character("a").asciiValue!)] += 1
            }
            if sArray == pArray {
                result.append(0)
            }
            for i in 0..<sCount - pCount {
                sArray[Int(s[s.index(s.startIndex, offsetBy: i)].asciiValue! - Character("a").asciiValue!)] -= 1
                sArray[Int(s[s.index(s.startIndex, offsetBy: i + pCount)].asciiValue! - Character("a").asciiValue!)] += 1
                if sArray == pArray {
                    result.append(i + 1)
                }
            }
            return result
        }
        
}

子串

1. 和为K的子数组

给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数

子数组是数组中元素的连续非空序列。

class Solution {
        func subarraySum(_ nums: [Int], _ k: Int) -> Int {
            var count = 0
            var pre = 0
            var map = Dictionary<Int, Int>()
            map[0] = 1
            for i in 0..<nums.count {
                pre += nums[i]
                let delta = pre - k
                if let value = map[delta] {
                    count += value
                }
                map[pre] = (map[pre] ?? 0) + 1
            }
            return count
        }
}

普通数组

1.最大子数组和

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

子数组 是数组中的一个连续部分。

    class Solution {
        func maxSubArray(_ nums: [Int]) -> Int {
            guard nums.count > 0 else {
                return 0
            }
            var pre = 0
            var maxResult = nums[0]
            for num in nums {
                pre = max(pre + num, num)
                maxResult = max(maxResult, pre)
            }
            return maxResult
        }
    }

2.合并区间

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。

class Solution {
        func merge(_ intervals: [[Int]]) -> [[Int]] {
            guard intervals.count > 0 else {
                return []
            }
            // 由大到小排列
            var sortedIntervals = intervals.sorted { left, right in
                left[0] > right[0]
            }
            var result = [[Int]]()
            result.append(sortedIntervals.removeLast())
            // 已经有元素了,开始比较
            while sortedIntervals.last != nil {
                let remainingLast = sortedIntervals.removeLast()
                if remainingLast[0] <= result.last![1] {
                    // 需要合并
                    let resultLast = result.removeLast()
                    result.append([resultLast[0], max(resultLast[1], remainingLast[1])])
                } else {
                    result.append(remainingLast)
                }
            }
            return result
        }
}

3.轮转数组

给定一个整数数组 nums,将数组中的元素向右轮转 k **个位置,其中 k **是非负数。

方案1:

class Solution {
        func rotate(_ nums: inout [Int], _ k: Int) {
            let count = nums.count
            var k = k % count
            // 现在k会小于count
            var totalCount = 0
            for i in 0..<count {
                if totalCount >= count {
                    break
                }
                var start = i
                var pre = nums[i]
                var current = i
                repeat {
                    var next = (k + current) % count
                    let tmp = nums[next]
                    nums[next] = pre
                    totalCount += 1
                    pre = tmp
                    current = next
                } while current != start
            }
            print(nums)
        }
}

方案2:

class Solution {
        func rotate(_ nums: inout [Int], _ k: Int) {
            let count = nums.count
            var k = k % count
            // 现在k会小于count
            nums.reverse()
            nums[0..<k].reverse()
            nums[k..<count].reverse()
            print(nums)
        }
}

4.除自身以外数组的乘积

给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。

题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在  32 位 整数范围内。

请 不要使用除法, 且在 O(n) 时间复杂度内完成此题。

class Solution {
        func productExceptSelf(_ nums: [Int]) -> [Int] {
            let count = nums.count
            var answer = Array(repeating: 0, count: count)
            answer[0] = 1
            // 得出元素i左边所有元素乘积的数组
            for index in 1..<count {
                answer[index] = answer[index - 1] * nums[index - 1]
            }
            var r = 1
            for index in (0..<count).reversed() {
                answer[index] = answer[index] * r
                r = r * nums[index]
            }
            return answer
        }
}

矩阵

1.矩阵置零

给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 [原地] 算法

class Solution {
        func setZeroes(_ matrix: inout [[Int]]) {
            guard matrix.count > 0 else {
                return
            }
            let row = matrix.count
            let column = matrix[0].count
            var rowFlag = Array(repeating: 0, count: row)
            var columFlag = Array(repeating: 0, count: column)
            for i in 0..<row {
                for j in 0..<column {
                    if matrix[i][j] == 0 {
                        print("i = (j), j = (j)")
                        rowFlag[i] = 1
                        columFlag[j] = 1
                    }
                }
            }
            for i in 0..<row {
                for j in 0..<column {
                    if rowFlag[i] == 1 || columFlag[j] == 1 {
                        matrix[i][j] = 0
                    }
                }
            }
        }
}

2.螺旋矩阵

给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

class Solution {
        func spiralOrder(_ matrix: [[Int]]) -> [Int] {
            var result = [Int]()
            let m = matrix.count
            let n = matrix[0].count
            var left = 0
            var right = n - 1
            var top = 0
            var bottom = m - 1
            while left <= right && top <= bottom {
                // 第一行向右走
                if left > right {
                    break
                }
                for j in left...right {
                    result.append(matrix[top][j])
                }
                top += 1
                if top > bottom {
                    break
                }
                for i in top...bottom {
                    result.append(matrix[i][right])
                }
                right -= 1
                if left > right {
                    break
                }
                for j in (left...right).reversed() {
                    result.append(matrix[bottom][j])
                }
                bottom -= 1
                if top > bottom {
                    break
                }
                for i in (top...bottom).reversed() {
                    result.append(matrix[i][left])
                }
                left += 1
            }
            return result
        }
}

3.旋转图像

给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。

你必须在 [原地] 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。

先上下翻转,再对角线翻转。

class Solution {
        func rotate(_ matrix: inout [[Int]]) {
            let m = matrix.count
            let n = matrix[0].count
            for i in 0..<(m / 2) {
                for j in 0..<n {
                    let tmp = matrix[m - i - 1][j]
                    matrix[m - i - 1][j] = matrix[i][j]
                    matrix[i][j] = tmp
                }
            }
            for i in 0..<m {
                for j in 0...i {
                    let tmp = matrix[j][i]
                    matrix[j][i] = matrix[i][j]
                    matrix[i][j] = tmp
                }
            }
            print(matrix)
        }
}

4.搜索二维矩阵II

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:

  • 每行的元素从左到右升序排列。
  • 每列的元素从上到下升序排列。
class Solution {
        func searchMatrix(_ matrix: [[Int]], _ target: Int) -> Bool {
            let m = matrix.count
            let n = matrix[0].count
            // 从右上角开始搜索
            var x = 0
            var y = n - 1
            while x < m && y >= 0 {
                if matrix[x][y] == target {
                    return true
                }
                if matrix[x][y] < target {
                    x += 1
                } else {
                    y -= 1
                }
            }
            return false
        }
}

链表

1.相交链表

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。

class Solution {
 func getIntersectionNode(_ headA: ListNode?, _ headB: ListNode?) -> ListNode? {
     var a = headA
    var b = headB
    if headA == nil || headB == nil {
        return nil
    }
    while a !== b {
        a = a == nil ? headB : a?.next
        b = b == nil ? headA : b?.next
    }
    return a
    }
}

2.反转链表

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

class Solution {
    func reverseList(_ head: ListNode?) -> ListNode? {
        var newHead: ListNode? = nil
        var currrent = head
        while currrent != nil {
            let next = currrent!.next
            currrent?.next = newHead
            newHead = currrent
            currrent = next
        }
        return newHead
    }
}

3.回文链表

给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。

方法1:将值复制到数组中后用双指针法

class Solution {
        func isPalindrome(_ head: ListNode?) -> Bool {
            var array = [ListNode]()
            var current = head
            while current != nil {
                array.append(current!)
                current = current?.next
            }
            let length = array.count
            guard length > 1 else {
                return true
            }
            var left = 0
            var right = length - 1
            while left <= right && array[left].val == array[right].val {
                left += 1
                right -= 1
            }
            if left > right {
                return true
            } else {
                return false
            }
        }
}

4.环形链表

给你一个链表的头节点 head ,判断链表中是否有环

class Solution {
        func hasCycle(_ head: ListNode?) -> Bool {
            var slow = head
            var fast = head?.next
            
            while slow != nil && fast != nil {
                if slow === fast {
                    return true
                } else {
                    slow = slow?.next
                    fast = fast?.next?.next
                }
            }
            return false
        }
}

5.环形链表II

给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

class Solution {
        func detectCycle(_ head: ListNode?) -> ListNode? {
            var slow = head
            var fast = head
            while fast?.next != nil {
                slow = slow?.next
                fast = fast?.next?.next
                if (slow === fast) {
                    var ptr = head
                    while ptr !== slow {
                        ptr = ptr?.next
                        slow = slow?.next
                    }
                    return ptr
                }
            }
            return nil
        }
}

6.合并两个有序链表

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

class Solution {
        func mergeTwoLists(_ list1: ListNode?, _ list2: ListNode?) -> ListNode? {
            var dumpNode: ListNode? = ListNode(-1, nil)
            var resultPreNode = dumpNode
            var list1 = list1
            var list2 = list2
            while list1 != nil && list2 != nil {
                if list1!.val <= list2!.val {
                    resultPreNode?.next = list1
                    list1 = list1?.next
                    resultPreNode = resultPreNode?.next
                } else {
                    resultPreNode?.next = list2
                    list2 = list2?.next
                    resultPreNode = resultPreNode?.next
                }
            }
            if list1 != nil {
                resultPreNode?.next = list1
            }
            if list2 != nil {
                resultPreNode?.next = list2
            }
            return dumpNode?.next
        }
}

7.两数相加

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

class Solution {
    func addTwoNumbers(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
        var dumpHead: ListNode? = ListNode(-1)
        var result = dumpHead
        var l1 = l1
        var l2 = l2
        var addition = 0
        while l1 != nil || l2 != nil {
            var sum = (l1?.val ?? 0) + (l2?.val ?? 0) + addition
            if sum >= 10 {
                addition = 1
                sum = sum - 10
            } else {
                addition = 0
            }
            result?.next = ListNode(sum)
            result = result?.next
            l1 = l1?.next
            l2 = l2?.next
        }
        if addition > 0 {
            result?.next = ListNode(1)
        }
        return dumpHead?.next
    }
}

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

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

class Solution {
        func removeNthFromEnd(_ head: ListNode?, _ n: Int) -> ListNode? {
            var dumpHead: ListNode? = ListNode(-1, head)
            var fast = dumpHead
            var fastPre = dumpHead
            for _ in 0..<n {
                fastPre = fast
                fast = fast?.next
                
            }
            if fast == nil && fastPre == nil {
                return head
            }
            var pre = dumpHead
            var slow = dumpHead
            while fast != nil {
                pre = slow
                slow = slow?.next
                fast = fast?.next
            }
            // 移除slow节点
            pre?.next = slow?.next
            return dumpHead?.next
        }
}

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

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。

class Solution {
        func swapPairs(_ head: ListNode?) -> ListNode? {
            if head == nil || head?.next == nil {
                return head
            }
            var newHead = head?.next
            head?.next = swapPairs(newHead?.next)
            newHead?.next = head
            return newHead
        }
}

11.随机链表的复制

给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。

构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点

class Solution {
        func copyRandomList(_ head: Node?) -> Node? {
            var dumpNewHead = Node(-1)
            var map: [ObjectIdentifier: Node] = [:]
            do {
                var newHead: Node? = dumpNewHead
                var oldHead = head
                while oldHead != nil {
                    // 先把next串起来
                    var newNode = Node(oldHead!.val)
                    map[ObjectIdentifier(oldHead!)] = newNode
                    newHead?.next = newNode
                    oldHead = oldHead?.next
                    newHead = newHead?.next
                }
            }
            do {
                var newHead: Node? = dumpNewHead.next
                var oldHead = head
                while oldHead != nil {
                    if let random = oldHead?.random {
                        newHead?.random = map[ObjectIdentifier(random)]
                    }
                    oldHead = oldHead?.next
                    newHead = newHead?.next
                }
            }
            return dumpNewHead.next
        }
    }

12.排序链表

给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。

class Solution
{
    func sortList(_ head: ListNode?) -> ListNode? 
    {
        if head == nil || head?.next == nil {
            return head
        }

        if head?.next?.next == nil{
            var temp = head?.next

            if head!.val > temp!.val{
                temp?.next = head
                head?.next = nil
                return temp
            }
            else{
                return head
            }
        }
        
        let leftList = head
        let middlePre = middleNode(head)
        let middle = middlePre?.next
        
        middlePre?.next = nil

        let left = sortList(leftList)
        let right = sortList(middle)

        return mergeTwoLists(left, right)
    }
    func mergeTwoLists(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
        
        if l1 == nil{
            return l2
        }
        
        if l2 == nil{
            return l1
        }
        
        var list1 = l1;
        var list2 = l2
        var prev : ListNode?
        
        let prehead : ListNode? = ListNode(-1)
        prev = prehead
        
        while list1 != nil && list2 != nil{
            
            if (list1?.val)! <= (list2?.val)!{
                prev?.next = list1
                list1 = list1?.next
            }
            else{
                prev?.next = list2
                list2 = list2?.next
            }
            prev = prev?.next
        }
        
        prev?.next = list1 ?? list2
        
        return prehead?.next
    }
    
    func middleNode(_ head: ListNode?) -> ListNode? {
           if head == nil || head?.next == nil{
               return head
           }

           if head?.next?.next == nil{
               return head?.next
           }

           var fast = head?.next
           var slow = head
           var pre = slow

           while fast != nil{
               pre = slow
               fast = fast?.next?.next
               slow = slow?.next
           }

           return pre
       }
}

13.困难

14.LRU缓存

请你设计并实现一个满足  LRU (最近最少使用) 缓存 约束的数据结构。

实现 LRUCache 类:

  • LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存
  • int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
  • void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字。

函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。

class ListNode: CustomStringConvertible {
    var description: String {
        return "value: (value.0),(value.1)"
    }
    
    var value: (Int, Int)
    var pre: ListNode?
    var next: ListNode?
    
    init(value: (Int, Int), pre: ListNode? = nil, next: ListNode? = nil) {
        self.value = value
        self.pre = pre
        self.next = next
    }
    
    
}

class List: CustomStringConvertible {
    
    var description: String {
        var result = ""
        var current: ListNode? = dumpHead
        while current != nil {
            result += current!.description
            result += "->"
            current = current?.next
        }
        return result
    }
    // 双向链表使用虚拟头、尾节点,方便操作。
    var dumpHead = ListNode(value: (-1, -1))
    var dumpTail = ListNode(value: (-1, -1))
    
    init() {
        dumpHead.next = dumpTail
        dumpTail.pre = dumpHead
    }
    
    func push(value: ListNode) {
        let nextNode = dumpHead.next
        value.next = nextNode
        nextNode?.pre = value
        dumpHead.next = value
        value.pre = dumpHead
    }
    
    func removeLast() -> ListNode? {
        let last = dumpTail.pre
        last?.pre?.next = dumpTail
        dumpTail.pre = last?.pre
        last?.pre = nil
        last?.next = nil
        return last
    }
    
    func remove(value: ListNode) {
        let previousNode = value.pre
        let nextNode = value.next
        previousNode?.next = nextNode
        nextNode?.pre = previousNode
    }
}

class LRUCache {
    
    private var map:[Int: ListNode] = [:]
    private var capacity = 0
    private var list = List()
    
    func showMap() {
        print(map)
        print(list)
    }
    
    init(_ capacity: Int) {
        self.capacity = capacity
    }
    
    func get(_ key: Int) -> Int {
        let value = map[key]
        if value == nil {
            return -1
        } else {
            defer {
                list.remove(value: value!)
                list.push(value: value!)
            }
            return value!.value.1
        }
        
    }
    
    func put(_ key: Int, _ value: Int) {
        if map[key] != nil {
            let node = map[key]!
            node.value = (key, value)
            list.remove(value: node)
            list.push(value: node)
            return
        }
        let newNode = ListNode(value: (key, value))
        if map.count >= capacity {
            if let removed = list.removeLast() {
                map[removed.value.0] = nil
            }
        }
        list.push(value: newNode)
        map[key] = newNode
    }
}

二叉树

1.二叉树的中序遍历

给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。

    class Solution {
        
        private var result: [Int] = []
        func inorderTraversal(_ root: TreeNode?) -> [Int] {
            self.inorderTraversal1(root)
            return result
        }
        
        private func inorderTraversal1(_ node: TreeNode?) {
            guard let node = node else {
                return
            }
            inorderTraversal1(node.left)
            result.append(node.val)
            inorderTraversal1(node.right)
        }
        
    }

2.二叉树的最大深度

给定一个二叉树 root ,返回其最大深度。

二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。

    class Solution {
        func maxDepth(_ root: TreeNode?) -> Int {
            return heightOfTree(root)
        }
        
        private func heightOfTree(_ node: TreeNode?) -> Int {
            guard let node = node else {
                return 0
            }
            let leftHeight = heightOfTree(node.left)
            let rightHeight = heightOfTree(node.right)
            return max(leftHeight, rightHeight) + 1
        }
    }