diff --git a/Week_01/id_29/leetcode_101_29.swift b/Week_01/id_29/leetcode_101_29.swift new file mode 100644 index 00000000..58022f2d --- /dev/null +++ b/Week_01/id_29/leetcode_101_29.swift @@ -0,0 +1,34 @@ +// +// leetcode_101_29.swift +// 极客时间 +// +// Created by gavin hu on 2019/6/23. +// Copyright © 2019 gavin hu. All rights reserved. +// + +import Foundation + +class Solution { + + /* + 思路:使用递归来实现 对称二叉树的规则是 左子树的左子树 等于 右子树的右子树 ,左子树的右子树等于 右子树的左子树 + */ + + func isMirror(_ left:TreeNode? ,_ right:TreeNode?) -> Bool{ + if left == nil && right != nil || left != nil && right == nil{ + return false + } + if left == nil && right == nil { + return true + } + + return left!.val == right!.val && + isMirror(left?.left, right?.right) && + isMirror(left?.right, right?.left) + } + + + func isSymmetric(_ root: TreeNode?) -> Bool { + return isMirror(root?.left,root?.right) + } +} diff --git a/Week_01/id_29/leetcode_1021_29.swift b/Week_01/id_29/leetcode_1021_29.swift new file mode 100644 index 00000000..249e42cd --- /dev/null +++ b/Week_01/id_29/leetcode_1021_29.swift @@ -0,0 +1,35 @@ +// +// leetcode_1021_29.swift +// 极客时间 +// +// Created by gavin hu on 2019/6/23. +// Copyright © 2019 gavin hu. All rights reserved. +// + +import Foundation + +class Solution { + + /* + 实现思路:要删除最外层的括号 所以第一个“(”不需要添加到新创建的字符串里面 保持l括号正确的情况下最后一个“)”不需要添加到新创建的字符串 + */ + + func removeOuterParentheses(_ S: String) -> String { + var res:String = String() + var left = 0 + for c in S { + if c == "(" { + left += 1 + if left > 1 { + res.append(c) + } + }else if c == ")" { + left -= 1 + if left > 0 { + res.append(c) + } + } + } + return res + } +} diff --git a/Week_01/id_29/leetcode_1047_29.swift b/Week_01/id_29/leetcode_1047_29.swift new file mode 100644 index 00000000..4647fab7 --- /dev/null +++ b/Week_01/id_29/leetcode_1047_29.swift @@ -0,0 +1,28 @@ +// +// leetcode_1047_29.swift +// 极客时间 +// +// Created by gavin hu on 2019/6/23. +// Copyright © 2019 gavin hu. All rights reserved. +// + +import Foundation +class Solution { + + /* + 实现思路:使用栈的方式,入栈的时候跟栈顶元素进行比较 如果栈顶元素等于当前元素 则弹出栈顶元素 + 否则入栈 + */ + + func removeDuplicates(_ S: String) -> String { + var res:String = String() + for c in S { + if res.isEmpty || res.last! != c{ + res.append(c) + }else { + res.popLast() + } + } + return res + } +} diff --git a/Week_01/id_29/leetcode_104_29.swift b/Week_01/id_29/leetcode_104_29.swift new file mode 100644 index 00000000..3c07ed07 --- /dev/null +++ b/Week_01/id_29/leetcode_104_29.swift @@ -0,0 +1,24 @@ +// +// leetcode_104_29.swift +// 极客时间 +// +// Created by gavin hu on 2019/6/23. +// Copyright © 2019 gavin hu. All rights reserved. +// + +import Foundation + +class Solution { + + /* + 思路:使用递归来实现 最大深度为左子树的最大深度 或者右子树的最大深度 中的最大值 + 1 + */ + + func maxDepth(_ root: TreeNode?) -> Int { + if root == nil { + return 0 + }else{ + return max(maxDepth(root?.left), maxDepth(root?.right)) + 1 + } + } +} diff --git a/Week_01/id_29/leetcode_111_29.swift b/Week_01/id_29/leetcode_111_29.swift new file mode 100644 index 00000000..f707cd76 --- /dev/null +++ b/Week_01/id_29/leetcode_111_29.swift @@ -0,0 +1,35 @@ +// +// leetcode_111_29.swift +// 极客时间 +// +// Created by gavin hu on 2019/6/23. +// Copyright © 2019 gavin hu. All rights reserved. +// + +import Foundation + +class Solution { + + /* + 使用递归: + 这里重写了 min 方法 + 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。在[1, 2]对应的树中,很明显,结点1不是叶子结点,结点2才是。所以比较的时候 如何左边是0 返回右边的最小值 ,右边是0 返回左边的最小值 左边小于右边返回左边 ,否则就是右边 + */ + + func min(_ a: Int, _ b: Int) -> Int { + if a == 0 { + return b + } else if b == 0 { + return a + } + return a < b ? a : b + } + + func minDepth(_ root: TreeNode?) -> Int { + guard let root = root else { return 0 } + + //min(minDepth(root?.left), minDepth(root?.right)) + + return min(minDepth_1(root.left), minDepth_1(root.right)) + 1 + } +} diff --git a/Week_01/id_29/leetcode_15_29.swift b/Week_01/id_29/leetcode_15_29.swift new file mode 100644 index 00000000..ca5fdf6d --- /dev/null +++ b/Week_01/id_29/leetcode_15_29.swift @@ -0,0 +1,132 @@ +// +// leetcode_15_29.swift +// 极客时间 +// +// Created by gavin hu on 2019/6/23. +// Copyright © 2019 gavin hu. All rights reserved. +// + +import Foundation + +class Solution { + /* + 方法一 暴力法 时间复杂度O(n^3) + */ + func threeSum(_ nums: [Int]) -> [[Int]] { + var result = [[Int]]() + for i in 0.. [[Int]] { + if nums.count < 3 { + return [[Int]]() + } + + var map:[Int:Int] = [Int:Int]() + + for i in 0.. 0 { + let num = [nums[i],nums[j],-(nums[i] + nums[j])].sorted() + if !result.contains(num) { + result.append(num) + } + } + } + } + } + return result + } +} + + +class Solution_2 { + + /* + 方法三 : 先排序 然后遍历 数组 ,遍历的时候才去两个指针一个从当前数的下一个开始 另一个从数组结尾开始 ,判断这两个数的和是否等于当前的数 + + */ + + func threeSum(_ nums: [Int]) -> [[Int]] { + if nums.count < 3 { + return [[Int]]() + } + var newNums = nums.sorted() + + var result:[[Int]] = [[Int]]() + + for i in 0.. 0 && newNums[i] == newNums[i-1] { + continue + } + + var left = i + 1 + var right = newNums.count - 1 + let need = 0 - newNums[i] + + while left < right { + if newNums[left] + newNums[right] == need { + + let num = [newNums[i],newNums[left],newNums[right]] + + result.append(num) + + + while left < right && newNums[left] == newNums[left + 1] { + left += 1 + } + while left < right && newNums[right] == newNums[right - 1] { + right -= 1 + } + + left += 1 + right -= 1 + + }else if newNums[left] + newNums[right] >= need { + right -= 1 + }else { + left += 1 + } + } + } + return result + } +} diff --git a/Week_01/id_29/leetcode_189_29.swift b/Week_01/id_29/leetcode_189_29.swift new file mode 100644 index 00000000..e8ffca98 --- /dev/null +++ b/Week_01/id_29/leetcode_189_29.swift @@ -0,0 +1,46 @@ +// +// leetcode_189_29.swift +// 极客时间 +// +// Created by gavin hu on 2019/6/23. +// Copyright © 2019 gavin hu. All rights reserved. +// + +import Foundation + + +/* + 采用取反的方式 + */ +class Solution { + + func rotate(_ nums: inout [Int], _ k: Int) { + var rotateCount = k + if k > nums.count { + rotateCount = k % nums.count + } + nums[0.. nums.count { + rotateCount = k % nums.count + } + while rotateCount > 0 { + let lastNum = nums.last! + for i in 0.. ListNode? { + if l1 == nil || l2 == nil { + return l1 == nil ? l2 : l1 + } + + if l1!.val < l2!.val { + l1?.next = mergeTwoLists(l1?.next, l2) + return l1 + }else{ + l2?.next = mergeTwoLists(l1, l2?.next) + return l2 + } + } +} diff --git a/Week_01/id_29/leetcode_242_29.swift b/Week_01/id_29/leetcode_242_29.swift new file mode 100644 index 00000000..85c54659 --- /dev/null +++ b/Week_01/id_29/leetcode_242_29.swift @@ -0,0 +1,77 @@ +// +// leetcode_242_29.swift +// 极客时间 +// +// Created by gavin hu on 2019/6/23. +// Copyright © 2019 gavin hu. All rights reserved. +// + +import Foundation + +class Solution { + + /* + 方法一: + #1 将字符串S 中的字符作为key 出现的次数作为value 存储到map 这个数据结构中 + #2 将字符串T 中的字符作为key 遍历是否在map 中有 ,如果有的话 所对应的value - 1 + #3 遍历这个map 是否存在value 不为1 的情况 如果存在 返回false + */ + + func isAnagram(_ s: String, _ t: String) -> Bool { + let char_s:[Character] = Array.init(s) + let char_t:[Character] = Array.init(t) + + var map:[Character:Int] = [Character:Int]() + + for char in char_s { + let count = (map[char] ?? 0) + 1 + map[char] = count + } + + for char in char_t { + let count = (map[char] ?? 0) - 1 + map[char] = count + } + + for val in map.values { + if val != 0 { + return false + } + } + + return true + } +} + +class Solution_1 { + + /* + 方法同 方法一 但是可以减少一次for循环 + */ + + func isAnagram(_ s: String, _ t: String) -> Bool { + let char_s:[Character] = Array.init(s) + let char_t:[Character] = Array.init(t) + + if char_s.count != char_t.count { + return false + } + + var map:[Character:Int] = [Character:Int]() + + for i in 0.. ListNode? { + let dummyHead = ListNode.init(-1) + dummyHead.next = head + + var pre = dummyHead + var cur = head + var next = head?.next + + while next != nil { + cur?.next = next?.next + next?.next = cur + pre.next = next + pre = cur! + cur = cur?.next + next = cur?.next + } + return dummyHead.next + } +} + + + +class Solution_1 { + /*: + 方法二 递归的方式去做 交换前面两个 然后后面的子串使用递归的方式继续交换 + */ + func swapPairs(_ head: ListNode?) -> ListNode? { + if head != nil || head?.next != nil { + return head + } + let next = head?.next + head?.next = swapPairs_1(next?.next) + next?.next = head + return next + } +} diff --git a/Week_01/id_29/leetcode_26_29.swift b/Week_01/id_29/leetcode_26_29.swift new file mode 100644 index 00000000..a8401935 --- /dev/null +++ b/Week_01/id_29/leetcode_26_29.swift @@ -0,0 +1,61 @@ +// +// leetcode_26_29.swift +// 极客时间 +// +// Created by gavin hu on 2019/6/23. +// Copyright © 2019 gavin hu. All rights reserved. +// + +import Foundation + + +class Solution { + + /*双指针法.慢指针维护目标排序位置,快指针用于遍历整个原数组.遍历时比较两指针的值,若相同则说明对于当前的 i 位置,快指针经历的 j 位置仍处于重复值,不同则时说明此时 nums[j] 是刚好紧邻且比 nums[i] 大的值,应当写入 nums[i+1] .最后别忘了右移 i.最终的长度比 i 多 1,故返回 i+1 即可. + + # 时间复杂度: O(n) + # 空间复杂度: O(1) +*/ + + func removeDuplicates(_ nums: inout [Int]) -> Int { + if nums.count == 0 || nums.count == 1 { + return nums.count + } + + var i = 0 + for j in 1.. Int { + if nums.count == 0 || nums.count == 1{ + return nums.count + } + var curNum = nums[0] + var index = 1 + while index < nums.count { + if curNum == nums[index] { + nums.remove(at: index) + }else{ + curNum = nums[index] + index += 1 + } + + } + return nums.count + } +} + + diff --git a/Week_01/id_29/leetcode_441_29.swift b/Week_01/id_29/leetcode_441_29.swift new file mode 100644 index 00000000..222bd21f --- /dev/null +++ b/Week_01/id_29/leetcode_441_29.swift @@ -0,0 +1,69 @@ +// +// leetcode_441_29.swift +// 极客时间 +// +// Created by gavin hu on 2019/6/23. +// Copyright © 2019 gavin hu. All rights reserved. +// + +import Foundation + +class Solution { + /* + 方法一 :暴力法 时间复杂度o(n) + */ + func arrangeCoins(_ n: Int) -> Int { + if n <= 1 { + return n + } + var row = 0 + var num = n + while row + 1 <= num { + row += 1 + num -= (row) + } + return row + } +} + + +class Solution1 { + /* + 方法二: 推导数学公式 row*(row+1) = 2n 时间复杂度o(n) + */ + + func arrangeCoins_1(_ n: Int) -> Int { + if n <= 1 { + return n + } + + var row = 1 + while row * (row + 1) <= 2*n { + row += 1 + } + return row - 1 + } +} + +class Solution2 { + /* + 方法三: 二分法 还是运用了 求和公式row*(row+1) = 2n ,但是我们这里在找这个row的时候 不是从1开始遍历 ,因为是有序的 所以我们可以 使用二分查找的方式 在1...n 里面进行查找 极大的提高查找效率 时间复杂度n(logn) + */ + + func arrangeCoins_2(_ n: Int) -> Int { + if n <= 1 { + return n + } + var left = 1 + var height = n + while left < height { + let mid = left + (height - left) / 2 + if mid * (mid + 1) / 2 <= n { + left = mid + 1 + }else{ + height = mid + } + } + return left - 1 + } +} diff --git a/Week_01/id_29/leetcode_49_29.swift b/Week_01/id_29/leetcode_49_29.swift new file mode 100644 index 00000000..736ea5ed --- /dev/null +++ b/Week_01/id_29/leetcode_49_29.swift @@ -0,0 +1,74 @@ +// +// leetcode_49_29.swift +// 极客时间 +// +// Created by gavin hu on 2019/6/23. +// Copyright © 2019 gavin hu. All rights reserved. +// + +import Foundation + +class Solution { + + /* + 方法一: + #1 遍历的时候 对数组里面的字符进行排序 ,并将其放入相应的map 里面 + #2 遍历map 获取它的所有value + 时间复杂度O(n)*O(klog(k)) + */ + + func groupAnagrams(_ strs: [String]) -> [[String]] { + var result:[[String]] = [[String]]() + + var map:[String:[String]] = [String:[String]]() + + for str in strs { + var strChars = Array.init(str) + strChars.sort() + if map[String.init(strChars)] == nil { + map[String.init(strChars)] = [str] + }else{ + map[String.init(strChars)]!.append(str) + } + } + + for val in map.values { + result.append(val) + } + + return result + } +} + +class Solution_1 { + + /* + 方法二: + */ + + func groupAnagrams(_ strs: [String]) -> [[String]] { + var result:[[String]] = [[String]]() + var map:[[Int]:[String]] = [[Int]:[String]]() + + for str in strs { + var num:[Int] = Array .init(repeating: 0, count: 26) + let strChars:[Character] = Array.init(str) + + for char in strChars { + let index = char.toInt() - Character.init("a").toInt() + num[index] = num[index] + 1 + } + + if map[num] == nil { + map[num] = [str] + }else{ + map[num]?.append(str) + } + } + + for val in map.values { + result.append(val) + } + return result + } +} diff --git a/Week_01/id_29/leetcode_50_29.swift b/Week_01/id_29/leetcode_50_29.swift new file mode 100644 index 00000000..ff392a77 --- /dev/null +++ b/Week_01/id_29/leetcode_50_29.swift @@ -0,0 +1,62 @@ +// +// leetcode_50_29.swift +// 极客时间 +// +// Created by gavin hu on 2019/6/23. +// Copyright © 2019 gavin hu. All rights reserved. +// + +import Foundation + + +class Solution { + /* + 方法一 :暴力法 遍历 1 到 n 每次都做 x*x 时间复杂度 O(n) + */ + + func myPow(_ x: Double, _ n: Int) -> Double { + if x == Double(0) { + return 0 + } + + if n == 0 { + return 1 + } + + var res:Double = 1 + let p = n < 0 ? -n : n + + for _ in 1...p { + res = res * x + } + return n > 0 ? res : 1/res + } +} + + +class Solution1 { + /* + 方法二 : 二分法 因为x^n = x^(n/2) * x^(n/2) 这样的话时间复杂度是O(log(n)) + */ + + func myPow_1(_ x: Double, _ n: Int) -> Double { + if x == Double(0) || n == 0 { + return 1 + } + + let p = n < 0 ? -n : n + var res:Double = 1 + + if n == 1 { + return x + } + res = myPow_1(x, p/2) + if p % 2 == 0 { + res = res * res + }else { + res = res * res * x + } + + return n > 0 ? res : 1/res + } +} diff --git a/Week_01/id_29/leetcode_783_29.swift b/Week_01/id_29/leetcode_783_29.swift new file mode 100644 index 00000000..c7eede20 --- /dev/null +++ b/Week_01/id_29/leetcode_783_29.swift @@ -0,0 +1,28 @@ +// +// leetcode_783_29.swift +// 极客时间 +// +// Created by gavin hu on 2019/6/23. +// Copyright © 2019 gavin hu. All rights reserved. +// + +import Foundation + +class Solution { + + func dfs(_ root: TreeNode? ,_ low:Int,_ high:Int , _ res:inout Int) { + if root == nil { return } + if low != Int.min { res = min(res, root!.val - low) } + if high != Int.min { res = min(res, high - root!.val) } + dfs(root?.left,low,root!.val,&res) + dfs(root?.right,root!.val,high,&res) + } + + + func minDiffInBST(_ root: TreeNode?) -> Int { + var res:Int = Int.max + dfs(root, Int.min, Int.max, &res) + return res + } + +} diff --git a/Week_01/id_29/leetcode_84_29.swift b/Week_01/id_29/leetcode_84_29.swift new file mode 100644 index 00000000..478c81c7 --- /dev/null +++ b/Week_01/id_29/leetcode_84_29.swift @@ -0,0 +1,71 @@ +// +// leetcode_84_29.swift +// 极客时间 +// +// Created by gavin hu on 2019/6/23. +// Copyright © 2019 gavin hu. All rights reserved. +// + +import Foundation + + + +class Solution { + + /* + 方法一 :暴力法 我们可以想到,两个柱子间矩形的高由它们之间最矮的柱子决定 因此,我们可以考虑所有两两柱子之间形成的矩形面积,该矩形的高为它们之间最矮柱子的高度,宽为它们之间的距离,这样可以找到所要求的最大面积的矩形。 + + 这个方法 时间复杂度是o(n^2) 空间复杂度 o(1) + + */ + + func largestRectangleArea(_ heights: [Int]) -> Int { + var area = 0 + for index in 0..= 0 && heights[cur - 1] >= heights[index] { + width += 1 + cur -= 1 + } + cur = index + while cur + 1 < heights.count && heights[cur + 1] > heights[index] { + width += 1 + cur += 1 + } + if width * heights[index] > area { + area = width * heights[index] + } + } + return area + } +} + + +class Solution_1 { + + /* + 方法二: + */ + + func largestRectangleArea(_ heights: [Int]) -> Int { + var area = 0 + var stack:[Int] = [Int]() + stack.append(-1) + + for index in 0..= 0 && j >= 0 { + if nums1[i] > nums2[j] { + nums1[k] = nums1[i] + i -= 1 + k -= 1 + }else { + nums1[k] = nums2[j] + k -= 1 + j -= 1 + } + } + + while j >= 0 { + nums1[k] = nums2[j] + k -= 1 + j -= 1 + } + } +} + + +class Solution2 { + /* + 新创建一个数组 空间复杂度O(n) 时间复杂度O(n) + */ + func merge(_ nums1: inout [Int], _ m: Int, _ nums2: [Int], _ n: Int) { + var array = [Int]() + + if n == 0 { + return + } + + var p = 0 ,q = 0 + + while p < m && q < n { + if nums1[p] < nums2[q] { + array.append(nums1[p]) + p += 1 + } else { + array.append(nums2[q]) + q += 1 + } + } + + if m > p { + for i in p.. q { + for i in q..