LeetCode题目:
Array:
func moveZeroes(_ nums: inout [Int]) {
var j = 0
for i in 0..<nums.count {
if nums[i] != 0 {
nums[j] = nums[i]
if (i != j) {
nums[i] = 0
}
j += 1
}
}
}
func maxArea(_ height: [Int]) -> Int {
// 2.双指针 移动短板方法
var left = 0, right = height.count - 1, res = 0
while left != right {
let area = min(height[left], height[right]) * (right - left)
res = max(area, res)
if height[left] <= height[right] {
left += 1
} else {
right -= 1
}
}
return res
}
-Bottom-up DP
func climbStairs(_ n: Int) -> Int {
if n == 1 {
return 1
}
var first = 1, second = 1, res = 0
for _ in 0..<n - 1 {
res = first + second
first = second
second = res
}
return res
}
-记忆化搜索(加缓存)
var memDict: Dictionary<Int, Int> = Dictionary<Int, Int>()
func climbStairs(_ n: Int) -> Int {
if n == 1 {
return 1
}
if n == 2 {
return 2
}
//memoize
guard (memDict[n] != nil) else {
memDict[n] = climbStairs(n - 1) + climbStairs(n - 2)
return memDict[n]!
}
return memDict[n]!
}
func threeSum(_ nums: [Int]) -> [[Int]] {
//非暴力 内层双指针夹逼法
if nums.count <= 2 {
return []
}
let sortedArray = nums.sorted(by: <)
var res: Array<Array<Int>> = []
for i in 0..<sortedArray.count - 2 {
// 略过i指向的重复元素
if i > 0 && sortedArray[i] == sortedArray[i - 1] {
continue
}
var j = i + 1
var k = sortedArray.count - 1
while j < k {
if sortedArray[i] + sortedArray[j] + sortedArray[k] == 0 {
res.append([sortedArray[i], sortedArray[j], sortedArray[k]])
// 略过j指向的重复元素
while j < k && sortedArray[j] == sortedArray[j + 1] {
j += 1
}
j += 1
} else if sortedArray[i] + sortedArray[j] + sortedArray[k] < 0 {
j += 1
} else {
k -= 1
}
}
}
return res
}
func twoSum(_ nums: [Int], _ target: Int) -> [Int] {
var dict = Dictionary<Int, Int>()
for (index, value) in nums.enumerated() {
if let value = dict[target - value] {
// 有值 返回结果
return [value, index]
} else {
// 没值 往字典里添
dict.updateValue(index, forKey: value)
}
}
return []
}
func removeDuplicates(_ nums: inout [Int]) -> Int {
var i = 0
let originNumsCount = nums.count
var deletedCount = 0
while i < nums.count - 1 {
if nums[i] == nums[i + 1] {
nums.remove(at:i)
deletedCount += 1
} else {
i += 1
}
}
return originNumsCount - deletedCount
}
-可以开一个新数组的情况下
func rotate(_ nums: inout [Int], _ k: Int) {
var newArray = nums
for (index, i) in nums.enumerated() {
let newIndex = (index + k) % nums.count
newArray[newIndex] = i
}
nums = newArray
}
-不开新数组的情况下
func rotate(_ nums: inout [Int], _ k: Int) {
if k == 0 {
return
}
for i in 0..<gcd(nums.count, k) {
var index = i
var cacheOutNum = nums[i]
repeat{
let newIndex = (index + k) % nums.count
let cacheInNum = nums[newIndex]
nums[newIndex] = cacheOutNum
cacheOutNum = cacheInNum
index = newIndex
}while index != i
}
}
-欧几里得算法公式解法:
// gcd(a, b) = gcd(b, a % b)
func gcd(_ a: Int, _ b: Int) -> Int {
let r = a % b
if r != 0 {
return gcd(b, r)
} else {
return b
}
}
-去0拼接然后排序
func merge(_ nums1: inout [Int], _ m: Int, _ nums2: [Int], _ n: Int) {
if n == 0 {
return
}
nums1.replaceSubrange((nums1.count - nums2.count)...(nums1.count - 1), with: nums2)
nums1.sort(by: <)
}
func plusOne(_ digits: [Int]) -> [Int] {
var mutableDigits = digits
// 最后一位不是9
if mutableDigits.last != 9 {
var last = mutableDigits.removeLast()
last += 1
mutableDigits.append(last)
} else {
var j = mutableDigits.count - 1
while mutableDigits[j] == 9 {
j -= 1
if j < 0 {
//全是9
return [1] + Array(repeating:0, count:mutableDigits.count)
}
}
// 到这说明不全是9 并且j指向的是第一个不为9的元素
mutableDigits[j] += 1
mutableDigits.replaceSubrange((j + 1)...mutableDigits.count - 1, with:Array(repeating: 0, count: mutableDigits.count - 1 - j))
}
return mutableDigits
}
Linked List :
func hasCycle(_ head: ListNode?) -> Bool {
var preNode = head
var nextNode = head?.next
while nextNode?.next != nil {
preNode = preNode?.next
nextNode = nextNode?.next?.next
if preNode?.val == nextNode?.val {
return true
}
}
return false
}
func detectCycle(_ head: ListNode?) -> ListNode? {
var slowNode: ListNode? = head
var fastNode: ListNode? = head
while true {
if fastNode == nil || fastNode?.next == nil {return nil}
fastNode = fastNode?.next?.next
slowNode = slowNode?.next
if fastNode === slowNode {break}
}
fastNode = head
while true {
if fastNode === slowNode {return fastNode}
fastNode = fastNode?.next
slowNode = slowNode?.next
}
}
func reverseList(_ head: ListNode?) -> ListNode? {
var dummyNode: ListNode? = nil
var currentNode = head
while currentNode != nil {
let nextNode = currentNode?.next
currentNode?.next = dummyNode
dummyNode = currentNode
currentNode = nextNode
}
return dummyNode
}
func swapPairs(_ head: ListNode?) -> ListNode? {
let dummyNode = ListNode(0)
var currentNode = dummyNode
dummyNode.next = head
while currentNode.next?.next != nil {
let node1 = currentNode.next
let node2 = currentNode.next?.next
currentNode.next = node2
node1?.next = node2?.next
node2?.next = node1
currentNode = node1!
}
return dummyNode.next
}
func reverseKGroup(_ head: ListNode?, _ k: Int) -> ListNode? {
let dummyNode: ListNode? = ListNode(0)
dummyNode?.next = head
var preNode: ListNode? = dummyNode
var endNode: ListNode? = dummyNode
while endNode?.next != nil {
for _ in 1...k {
endNode = endNode?.next
}
if endNode == nil {break}
let startNode = preNode?.next
let nextNode = endNode?.next
endNode?.next = nil
preNode?.next = reverseList(startNode)
startNode?.next = nextNode
preNode = startNode
endNode = startNode
}
return dummyNode?.next
}
func reverseList(_ head: ListNode?) -> ListNode? {
var dummyNode: ListNode? = nil
var currentNode = head
while currentNode != nil {
var nextNode = currentNode?.next
currentNode?.next = dummyNode
dummyNode = currentNode
currentNode = nextNode
}
return dummyNode
}
func mergeTwoLists(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
var varL1 = l1
var varL2 = l2
let dummyNode: ListNode? = ListNode(0)
var preNode = dummyNode
while varL1 != nil && varL2 != nil {
if varL1!.val <= varL2!.val {
preNode?.next = varL1
preNode = varL1
varL1 = varL1?.next
} else {
preNode?.next = varL2
preNode = varL2
varL2 = varL2?.next
}
}
if varL1 == nil {
preNode?.next = varL2
} else {
preNode?.next = varL1
}
return dummyNode?.next
}
-三指针,挪动大的,最后把j中剩下的按位置替换到nums1中的数据
func merge(_ nums1: inout [Int], _ m: Int, _ nums2: [Int], _ n: Int) {
if m == 0 {
nums1 = nums2
return
} else if n == 0 {
return
}
var i = m - 1, j = n - 1, k = m + n - 1
while i >= 0 && j >= 0 {
if nums2[j] >= nums1[i] {
nums1[k] = nums2[j]
k -= 1
j -= 1
} else {
nums1[k] = nums1[i]
k -= 1
i -= 1
}
}
nums1[..<(j + 1)] = nums2[..<(j + 1)]
}
}
Stack
class MinStack {
var stack = Array<Int>()
var minStack = Array<Int>()
init() {}
func push(_ x: Int) {
stack.append(x)
guard let min = minStack.last, min < x else {
minStack.append(x)
return
}
}
func pop() {
if stack.last == minStack.last {
minStack.popLast()
}
stack.popLast()
}
func top() -> Int {
return stack.last!
}
func getMin() -> Int {
return minStack.last!
}
}
func isValid(_ s: String) -> Bool {
let dict = ["(" : ")", "{" : "}", "[" : "]"]
var stack = Array<String>()
for c in s {
if c == "(" || c == "{" || c == "[" {
stack.append(String(c))
} else {
// 右括号
guard let cur = stack.popLast() else {
return false
}
if dict[String(cur)] != String(c) {
return false
}
}
}
return (stack.count != 0) ? false : true
}
func largestRectangleArea(_ heights: [Int]) -> Int {
let len = heights.count
if len == 0 {
return 0
}
if len == 1 {
return heights[0]
}
var area = 0
let newHeights = [0] + heights + [0]
var stack = Array<Int>()
stack.append(0)
for i in 1...newHeights.count - 1 {
while (newHeights[stack.last!] > newHeights[i]) {
let height = newHeights[stack.removeLast()]
let width = i - stack.last! - 1
area = max(area, width * height)
}
stack.append(i)
}
return area
}
class Solution {
func trap(_ height: [Int]) -> Int {
var stack = Array<Int>()
var res = 0
var currentIndex = 0
while currentIndex < height.count {
while !stack.isEmpty && height[currentIndex] > height[stack.last!] {
let cancalculateIndex = stack.removeLast()
if stack.isEmpty {
break
}
let width = currentIndex - stack.last! - 1
let height = min(height[stack.last!], height[currentIndex]) - height[cancalculateIndex]
res += width * height
}
stack.append(currentIndex)
currentIndex += 1
}
return res
}
}
Queue
class MyCircularDeque {
var circularQueue = Array<Int>()
var capacity = 0
/** Initialize your data structure here. Set the size of the deque to be k. */
init(_ k: Int) {
capacity = k
}
/** Adds an item at the front of Deque. Return true if the operation is successful. */
func insertFront(_ value: Int) -> Bool {
if isFull() {return false}
circularQueue = [value] + circularQueue
return true
}
/** Adds an item at the rear of Deque. Return true if the operation is successful. */
func insertLast(_ value: Int) -> Bool {
if isFull() {return false}
circularQueue.append(value)
return true
}
/** Deletes an item from the front of Deque. Return true if the operation is successful. */
func deleteFront() -> Bool {
if isEmpty() {return false}
circularQueue.removeFirst()
return true
}
/** Deletes an item from the rear of Deque. Return true if the operation is successful. */
func deleteLast() -> Bool {
if isEmpty() {return false}
circularQueue.removeLast()
return true
}
/** Get the front item from the deque. */
func getFront() -> Int {
guard let front = circularQueue.first else {
return -1
}
return front
}
/** Get the last item from the deque. */
func getRear() -> Int {
guard let rear = circularQueue.last else {
return -1
}
return rear
}
/** Checks whether the circular deque is empty or not. */
func isEmpty() -> Bool {
return circularQueue.count == 0 ? true : false
}
/** Checks whether the circular deque is full or not. */
func isFull() -> Bool {
return circularQueue.count == capacity ? true : false
}
}
/**
* Your MyCircularDeque object will be instantiated and called as such:
* let obj = MyCircularDeque(k)
* let ret_1: Bool = obj.insertFront(value)
* let ret_2: Bool = obj.insertLast(value)
* let ret_3: Bool = obj.deleteFront()
* let ret_4: Bool = obj.deleteLast()
* let ret_5: Int = obj.getFront()
* let ret_6: Int = obj.getRear()
* let ret_7: Bool = obj.isEmpty()
* let ret_8: Bool = obj.isFull()
*/
class Solution {
// 优先队列,超出时间限制了
// func maxSlidingWindow(_ nums: [Int], _ k: Int) -> [Int] {
// if k == nums.count {
// return [nums.max()!]
// }
// var heap = Heap<(Int)>(array: Array(nums[0..<k]), sort: >)
// var ans = Array<Int>()
// ans.append(heap.peek()!)
// for i in 1...nums.count - k {
// heap.remove(at: heap.index(of: nums[i - 1])!)
// heap.insert(nums[i + k - 1])
// ans.append(heap.peek()!)
// }
// return ans
// }
func maxSlidingWindow(_ nums: [Int], _ k: Int) -> [Int] {
var circularQueue = Array<Int>()
var ans = Array<Int>()
for i in 0..<k {
while circularQueue.count != 0 && nums[i] >= nums[circularQueue.last!] {
circularQueue.removeLast()
}
circularQueue.append(i)
}
ans.append(nums[circularQueue.first!])
for i in k..<nums.count {
while circularQueue.count != 0 && nums[i] >= nums[circularQueue.last!] {
circularQueue.removeLast()
}
circularQueue.append(i)
// 弹出超界下标
while circularQueue.count != 0 && (i - k) >= circularQueue.first! {
circularQueue.removeFirst()
}
ans.append(nums[circularQueue.first!])
}
return ans
}
}
public struct Heap<T> {
/** The array that stores the heap's nodes. */
var nodes = [T]()
/**
* Determines how to compare two nodes in the heap.
* Use '>' for a max-heap or '<' for a min-heap,
* or provide a comparing method if the heap is made
* of custom elements, for example tuples.
*/
private var orderCriteria: (T, T) -> Bool
/**
* Creates an empty heap.
* The sort function determines whether this is a min-heap or max-heap.
* For comparable data types, > makes a max-heap, < makes a min-heap.
*/
public init(sort: @escaping (T, T) -> Bool) {
self.orderCriteria = sort
}
/**
* Creates a heap from an array. The order of the array does not matter;
* the elements are inserted into the heap in the order determined by the
* sort function. For comparable data types, '>' makes a max-heap,
* '<' makes a min-heap.
*/
public init(array: [T], sort: @escaping (T, T) -> Bool) {
self.orderCriteria = sort
configureHeap(from: array)
}
/**
* Configures the max-heap or min-heap from an array, in a bottom-up manner.
* Performance: This runs pretty much in O(n).
*/
private mutating func configureHeap(from array: [T]) {
nodes = array
for i in stride(from: (nodes.count/2-1), through: 0, by: -1) {
shiftDown(i)
}
}
public var isEmpty: Bool {
return nodes.isEmpty
}
public var count: Int {
return nodes.count
}
/**
* Returns the index of the parent of the element at index i.
* The element at index 0 is the root of the tree and has no parent.
*/
@inline(__always) internal func parentIndex(ofIndex i: Int) -> Int {
return (i - 1) / 2
}
/**
* Returns the index of the left child of the element at index i.
* Note that this index can be greater than the heap size, in which case
* there is no left child.
*/
@inline(__always) internal func leftChildIndex(ofIndex i: Int) -> Int {
return 2*i + 1
}
/**
* Returns the index of the right child of the element at index i.
* Note that this index can be greater than the heap size, in which case
* there is no right child.
*/
@inline(__always) internal func rightChildIndex(ofIndex i: Int) -> Int {
return 2*i + 2
}
/**
* Returns the maximum value in the heap (for a max-heap) or the minimum
* value (for a min-heap).
*/
public func peek() -> T? {
return nodes.first
}
/**
* Adds a new value to the heap. This reorders the heap so that the max-heap
* or min-heap property still holds. Performance: O(log n).
*/
public mutating func insert(_ value: T) {
nodes.append(value)
shiftUp(nodes.count - 1)
}
/**
* Adds a sequence of values to the heap. This reorders the heap so that
* the max-heap or min-heap property still holds. Performance: O(log n).
*/
public mutating func insert<S: Sequence>(_ sequence: S) where S.Iterator.Element == T {
for value in sequence {
insert(value)
}
}
/**
* Allows you to change an element. This reorders the heap so that
* the max-heap or min-heap property still holds.
*/
public mutating func replace(index i: Int, value: T) {
guard i < nodes.count else { return }
remove(at: i)
insert(value)
}
/**
* Removes the root node from the heap. For a max-heap, this is the maximum
* value; for a min-heap it is the minimum value. Performance: O(log n).
*/
@discardableResult public mutating func remove() -> T? {
guard !nodes.isEmpty else { return nil }
if nodes.count == 1 {
return nodes.removeLast()
} else {
// Use the last node to replace the first one, then fix the heap by
// shifting this new first node into its proper position.
let value = nodes[0]
nodes[0] = nodes.removeLast()
shiftDown(0)
return value
}
}
/**
* Removes an arbitrary node from the heap. Performance: O(log n).
* Note that you need to know the node's index.
*/
@discardableResult public mutating func remove(at index: Int) -> T? {
guard index < nodes.count else { return nil }
let size = nodes.count - 1
if index != size {
nodes.swapAt(index, size)
shiftDown(from: index, until: size)
shiftUp(index)
}
return nodes.removeLast()
}
/**
* Takes a child node and looks at its parents; if a parent is not larger
* (max-heap) or not smaller (min-heap) than the child, we exchange them.
*/
internal mutating func shiftUp(_ index: Int) {
var childIndex = index
let child = nodes[childIndex]
var parentIndex = self.parentIndex(ofIndex: childIndex)
while childIndex > 0 && orderCriteria(child, nodes[parentIndex]) {
nodes[childIndex] = nodes[parentIndex]
childIndex = parentIndex
parentIndex = self.parentIndex(ofIndex: childIndex)
}
nodes[childIndex] = child
}
/**
* Looks at a parent node and makes sure it is still larger (max-heap) or
* smaller (min-heap) than its childeren.
*/
internal mutating func shiftDown(from index: Int, until endIndex: Int) {
let leftChildIndex = self.leftChildIndex(ofIndex: index)
let rightChildIndex = leftChildIndex + 1
// Figure out which comes first if we order them by the sort function:
// the parent, the left child, or the right child. If the parent comes
// first, we're done. If not, that element is out-of-place and we make
// it "float down" the tree until the heap property is restored.
var first = index
if leftChildIndex < endIndex && orderCriteria(nodes[leftChildIndex], nodes[first]) {
first = leftChildIndex
}
if rightChildIndex < endIndex && orderCriteria(nodes[rightChildIndex], nodes[first]) {
first = rightChildIndex
}
if first == index { return }
nodes.swapAt(index, first)
shiftDown(from: first, until: endIndex)
}
internal mutating func shiftDown(_ index: Int) {
shiftDown(from: index, until: nodes.count)
}
}
extension Heap where T: Equatable {
/** Get the index of a node in the heap. Performance: O(n). */
public func index(of node: T) -> Int? {
return nodes.index(where: { $0 == node })
}
/** Removes the first occurrence of a node from the heap. Performance: O(n). */
@discardableResult public mutating func remove(node: T) -> T? {
if let index = index(of: node) {
return remove(at: index)
}
return nil
}
}
网友评论