# 前言

• 数组、字符串、集合、字典相关的基础算法
• 链表
• 栈和队列

# 一、集合和字典相关算法

1、已知一个整形数组(arr)以及一个整数(sum)，判断数组中是否存在两个数字之和等于这个整数（sum）？
2、求这两个数字在数组中的下标 (注意第一问中应该是有且只有两个数字等于这个整数 sum )。

``````func isExist(arr:[Int],sum:Int) -> Bool {
var set = Set<Int>()
for num in arr {
if set.contains(sum - num){
return true
}
set.insert(num)
}
return false
}
``````

``````func getIndex(arr:[Int],sum:Int)->[Int]{
var dict = [Int:Int]()
for (i,num) in arr.enumerated(){
if let idx = dict[sum-num]{
return [idx,i]
}else{
dict[num] = I
}
}
fatalError("没有满足条件的下标")
}
``````

# 二、字符串相关算法

• 整个句子的翻转
• 句子中的每个单词的翻转

Given an input string, reverse the string word by word. A word is defined as a sequence of non-space characters. The input string does not contain leading or trailing spaces and the words are always separated by a single space. For example, Given s = "the sky is blue", return "blue is sky the". Could you do it in-place without allocating extra space?

`````` func reverseWords(s: String?) -> String? {
guard let s = s else {
return nil
}
var chars = Array(s.characters)
var start = 0
//从头到尾置整个字符串，此步得到的结果为：eulb si yks eht
reverseWord(&chars, 0, chars.count - 1)
//找到每一个单词对用的首尾index,然后翻转每一个单词
for i in 0 ..< chars.count {
print(chars[I])
if i == chars.count - 1 || chars[i + 1] == " " {
print(i)
print(start)
reverseWord(&chars, start, i)
start = i + 2
}
}
return String(chars)
}

//从头到尾置换数组中的元素
fileprivate func reverseWord<T>(_ chars: inout [T], _ start: Int, _ end: Int) {
var start = start, end = end
while start < end {
swapCharacter(&chars, start, end)
start += 1
end -= 1
}
}

//交换数组中的两个元素
fileprivate func swapCharacter<T>(_ chars: inout [T], _ p: Int, _ q: Int) {
(chars[p], chars[q]) = (chars[q], chars[p])
}
``````

`````` var s = "the sky is blue"
print(reverseWords(s: s))
``````

# 三、链表

##### 基本实现

``````class ListNode {
var value:Int
var next:ListNode?

init(value:Int) {
self.value = value
self.next = nil
}
}
``````

``````class List {
var tail:ListNode?

// 头插法
} else {
let temp = ListNode(value:val)
}
}

// 尾插法
func appendToTail(val: Int) {
if tail == nil {
tail = ListNode(value:val)
} else {
tail!.next = ListNode(value:val)
tail = tail!.next
}
}
}
``````

``````let list = List()
list.appendToTail(val: 1)
list.appendToTail(val: 2)
list.appendToTail(val: 3)
``````

# 四、栈和队列(包含数组)

##### 栈和队列的实现

``````class Stack {
//储存栈上的元素
var arr:[Any]
init() {
arr = [Any]()
}
//判断栈是否为空
var isEmpty:Bool{
return arr.isEmpty
}
//获取栈顶元素
var peek:Any?{
return arr.last
}
//push操作
func push(obj:Any) {
arr.append(obj)
}
//pop操作
func pop() -> Any? {
if self.isEmpty{
return nil
}else{
//注意removeLast()返回值为移除的对象
return arr.removeLast()
}
}
}
``````
``````//调用形式
let stack = Stack()
stack.push(obj: 1)
stack.push(obj: 2)
stack.push(obj: 3)
print(stack.pop())//打印结果为:Optional(3)
``````

``````class Queue {
//储存队列上的元素
var arr:[Any]

init() {
arr = [Any]()
}

//判断队列是否为空
var isEmpty:Bool{
return arr.isEmpty
}
//获取队列首元素
var firstObj:Any?{
return arr.last
}
/// 加入新元素
public func enqueue(obj: Any) {
arr.append(obj)
}
/// 推出队列元素
public func dequeue() -> Any? {
if isEmpty {
return nil
} else {
return arr.removeFirst()
}
}
}
``````
``````//调用形式
let queue = Queue()
queue.enqueue(obj: 1)
queue.enqueue(obj: 2)
queue.enqueue(obj: 3)
print(queue.dequeue())//打印结果为:Optional(1)
``````
``````Given an absolute path for a file (Unix-style), simplify it.For example,
path = "/home/", => "/home"
path = "/a/./b/../../c/", => "/c"
``````

``````    func finalPath(pathStr:String) -> String {
let pathStack = Stack()
let paths = pathStr.components(separatedBy: "/")
for path in paths{
// 对于 "." 我们直接跳过
guard path != "." else {
continue
}
// 对于 ".." 执行pop操作
if path == ".."  {
if pathStack.isEmpty == false {
pathStack.pop()
}
}else if path != "" {// 对于空数组的特殊情况
pathStack.push(obj: path)
}
}
//print(pathStack.arr)
// 将栈中的内容转化为优化后的新路径
let result = pathStack.arr.reduce("") { total, dir in "\(total)/\(dir)" }
// 注意空路径的结果是 "/"
return result.isEmpty ? "/" : result
}
``````
``````//调用形式
print(finalPath(pathStr: "/a/./b/c/../../d/"))//打印结果为:/a/d
print(finalPath(pathStr: "/a/./b/../../c/"))//打印结果为:/c
``````
iOS - 综合技能