Swift: Math Algorithm
BFS
BFS and DFS Templates Algorithms in Swift
LRU - Least Recently Used
https://www.jianshu.com/p/e09870b60046
那什么是 LruCache 呢?其实 LRU(Least Recently Used) 的意思就是近期最少使用算法,它的核心思想就是会优先淘汰那些近期最少使用的缓存对象。
class ListNode {
var key: Int
var value: Int
var next: ListNode?
var prev: ListNode?
init(key: Int, value: Int) {
self.key = key
self.value = value
}
}
class LRUCache {
private var cache = [Int: ListNode]()
// 最大size
private var max_size = 0
// 当前size
private var cur_size = 0
// 头
private var head: ListNode?
// 尾
private var tail: ListNode?
init(_ capacity: Int) {
max_size = capacity
}
public func get(_ key: Int) -> Int {
if let node = cache[key] {
moveToHead(node: node)
return node.value
}
return -1
}
public func put(_ key: Int, _ value: Int) {
if let node = cache[key] {
node.value = value
moveToHead(node: node)
} else {
let node = ListNode(key: key, value: value)
addNode(node: node)
cache[key] = node
cur_size += 1
if cur_size > max_size {
removeTail()
cur_size -= 1
}
}
}
/// 添加节点到头部
private func addNode(node: ListNode) {
if self.head == nil {
self.head = node
self.tail = node
} else {
let temp = self.head!
self.head = node
self.head?.next = temp
temp.prev = self.head
}
}
/// 移动到头部
private func moveToHead(node: ListNode) {
if node === self.head {
return
}
let prev = node.prev
let next = node.next
prev?.next = next
if next != nil {
next!.prev = prev
} else {
self.tail = prev
}
let origin = self.head
self.head = node
self.head?.next = origin
origin?.prev = self.head
}
/// 删除尾部
@discardableResult
private func removeTail() -> ListNode? {
if let tail = self.tail {
cache.removeValue(forKey: tail.key)
self.tail = tail.prev
self.tail?.next = nil
return tail
}
return nil
}
}
let cache = LRUCache(3)
cache.put(1, 1)
cache.put(2, 2)
cache.put(3, 3)
cache.put(4, 4)
print(cache.get(4))
print(cache.get(3))
print(cache.get(2))
print(cache.get(1))
print("==========")
cache.put(5, 5)
print(cache.get(1))
print(cache.get(2))
print(cache.get(3))
print(cache.get(4))
print(cache.get(5))
/**
print("==========")
4
3
2
-1
==========
-1
2
3
-1
5
==========
*/
Dynamic Programming
一个例子带你走进动态规划 – 青蛙跳阶问题
暴力递归
★leetcode原题:一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 10 级的台阶总共有多少种跳法。
有些小伙伴第一次见这个题的时候,可能会有点蒙圈,不知道怎么解决。其实可以试想:
- 要想跳到第10级台阶,要么是先跳到第9级,然后再跳1级台阶上去;要么是先跳到第8级,然后一次迈2级台阶上去。
- 同理,要想跳到第9级台阶,要么是先跳到第8级,然后再跳1级台阶上去;要么是先跳到第7级,然后一次迈2级台阶上去。
- 要想跳到第8级台阶,要么是先跳到第7级,然后再跳1级台阶上去;要么是先跳到第6级,然后一次迈2级台阶上去。
”
假设跳到第n级台阶的跳数我们定义为f(n),很显然就可以得出以下公式:
Tree
Preorder Traverse
二叉树的前序遍历
class Solution {
func preorderTraversal(_ root: TreeNode?) -> [Int] {
var res: [Int] = []
if nil == root {
return res
}
var stack: [TreeNode?] = []
var node: TreeNode? = root
while !stack.isEmpty || nil != node {
while nil != node {
res.append(node!.val)
stack.append(node)
node = node?.left
}
node = stack.removeLast()?.right
}
return res
}
}
Prime Number
A prime number is a whole number greater than 1 whose only factors are 1 and itself.
2, 3, 5, 7, 11, 13, 17, 19, 23, 29 are prime numbers.
Swift 4.2, Xcode 10.1
This prime checking function and extension is the most efficient as it checks the divisibility of only $\frac{1}{2}\sqrt{n}$ integers.
Complexity: $O(\frac{1}{2} \sqrt{n})$
/// https://stackoverflow.com/questions/31105664/check-if-a-number-is-prime
/// Check if a number is prime?
import Foundation
func isPrime(for number: Int) -> Bool {
guard number >= 2 else { return false }
guard number != 2 else { return true }
guard number % 2 != 0 else { return false }
/// `stride(from: 3, to: Int(sqrt(Double(number))), by: 2)`
/// traverse 3 5 7 9 11.... odd number
///
/// `stride(from:to:by:).contains(where:)`
/// If number % index = 1, then it's not prime.
/// If the odd number contains number that the specific number can be divided by. Then it's not prime.
/// So there is a negation operator before stride.
/// True -> Prime False -> Not Prime
return !stride(from: 3, to: Int(sqrt(Double(number))), by: 2).contains(where: { index in
return number % index == 0
})
}
print(isPrime(for: 4))
Extension
extension Int {
/// A prime number is a whole number greater than 1 whose only factors are 1 and itself.
var isPrime: Bool {
guard self >= 2 else { return false }
guard self != 2 else { return true }
guard self % 2 != 0 else { return false }
return !stride(from: 3, to: Int(sqrt(Double(self))), by: 2).contains(where: { index in
return self % index == 0
})
}
}
var number = 3
number.isPrime
Get odd number in C
- Store the size of the array to be returned in the
result_count
variable - Allocate the array statically or dynamically.
C get odd numbers between a range and store it in int array - by user10543939 on the stack overflow
int* oddNumbers(int start, int end, int* result_count) {
int *result;
int i;
/// @brief #define assert(e) \
/// (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __ASSERT_FILE_NAME, __LINE__, #e) : (void)0)
/// @param start
/// @param end
/// @param result_count
/// @return
assert(result_count && start <= end && INT8_MIN < end);
// if start is even, then add 1 to be odd
start += !(start % 2);
// if end is even, then minus 1 to be odd
end -= !(end % 2);
// calculate array size
*result_count = (end - start) / 2 + 1;
result = malloc(*result_count * sizeof(result));
if(!result) return NULL;
// fill in numbers in the result
for (i = 0; start <= end; i++, start += 2) result[i] = start;
return result;
}
int main() {
int min = 30;
int max = 85;
// address of count
int count;
int *numbers = oddNumbers(min, max, &count);
for (int i = 0; i < count; i++) {
printf("%d ", numbers[i]);
}
// Don't forget to `free()` the returned pointer when you are done using it.
free(numbers);
}
Stride and generics template in C++
template<typename T>
T * stride(T start, T end, T step) {
T * arrayOfOutPut;
int sizeOfArray = (end - start) / step + 1;
arrayOfOutPut = (T *)malloc(sizeOfArray * sizeof(T));
for(int i = 0; i < sizeOfArray; i++) {
arrayOfOutPut[i] = start + i * step;
std::cout << arrayOfOutPut[i] << " ";
}
return arrayOfOutPut;
}
int main() {
double start = 2;
double end = 5;
double step = 0.5;
int sizeOfArray = (end - start) / step + 1;
double* a = stride(start, end, step);
std::cout << std::endl;
for(int i = 0; i < sizeOfArray; i++) {
std::cout << a[i] << " ";
}
}
valarray
#include <iostream>
#include <valarray>
bool isPrime(int number) {
if (!(number > 2)) return false;
if (!(number != 2)) return true;
if (!(number % 2 != 0)) return false;
int end = number;
int start = 3;
int step = 2;
int sizeOfArray = sizeOfArray = (end - start) / step + 1;
std::valarray<int> array(sizeOfArray);
for(int i = 0; i < sizeOfArray; i++) {
array[i] = i;
}
std::slice slcOfArray(start, end, step);
std::valarray<int> valArrayOutput = std::valarray<int>(array[slcOfArray]);
for(int i = 0; i < sizeOfArray; i++) {
if (number % valArrayOutput[i] == 0) return false;
}
return true;
}
int main() {
int numberCount = 0;
int startNumber = 200;
int endNumber = 299;
for(int i = startNumber; i <= endNumber; i++) {
if(isPrime(i)) {
numberCount += 1;
std::cout << i;
if(numberCount == 8) {
std::cout << std::endl;
numberCount = 0;
} else {
std::cout << " ";
}
}
}
}
Sieve of Eratosthenes
Sieve of Eratosthenes - GeeksForGeeks
Khan Academy - Sieve of Eratosthenes
For all numbers a: from 2 to sqrt(n)
IF a is unmarked THEN
a is prime
for all multiples of a (a < n)
mark multiples as composite
All unmarked numbers are prime!
#include <stdio.h>
void SieveOfEratosthenes(int n) {
bool prime[n + 1];
}