iOS面试算法基础(1)-基本数据结构

数组

数组是最基本的数据结构。在 Swift 中,以前 Objective-C 时代中将 NSMutableArray 和 NSArray 分开的做法,被统一到了唯一的数据结构 —— Array 。虽然看上去就一种数据结构,其实它的实现有三种:

ContiguousArray:效率最高,元素分配在连续的内存上。如果数组是值类型(栈上操作),则 Swift 会自动调用 Array 的这种实现;如果注重效率,推荐声明这种类型,尤其是在大量元素是类时,这样做效果会很好。

Array:会自动桥接到 Objective-C 中的 NSArray 上,如果是值类型,其性能与 ContiguousArray 无差别。

ArraySlice:它不是一个新的数组,只是一个片段,在内存上与原数组享用同一区域。

字典和集合

字典和集合(这里专指HashSet)经常被使用的原因在于,查找数据的时间复杂度为 O(1)。

一般字典和集合要求它们的 Key 都必须遵守 Hashable 协议,Cocoa 中的基本数据类型都

满足这一点;自定义的 class 需要实现 Hashable,而又因为 Hashable 是对 Equable 的扩展,

所以还要重载 == 运算符。

集合和字典在实战中经常与数组配合使用,请看下面这道算法题:

给一个整型数组和一个目标值,判断数组中是否有两个数字之和等于目标值

这道题是传说中经典的 “2Sum”,我们已经有一个数组记为 nums,也有一个目标值记为 target,最后要返回一个 Bool 值。

最粗暴的方法就是每次选中一个数,然后遍历整个数组,判断是否有另一个数使两者之和为 target。这种做法时间复杂度为 O(n^2)。

采用集合可以优化时间复杂度。在遍历数组的过程中,用集合每次保存当前值。假如集合中已经有了目标值减去当前值,则证明在之前的遍历中一定有一个数与当前值之和等于目标值。这种做法时间复杂度为 O(n)

如果把题目稍微修改下,变为

给定一个整型数组中有且仅有两个数字之和等于目标值,求两个数字在数组中的序号

字符串和字符

字符串在算法实战中极其常见。在 Swift 中,字符串不同于其他语言(包括 Objective-C),它是值类型而非引用类型,它是多个字符构成的序列(并非数组)。

关于字符串,我们来一起看一道以前的 Google 面试题。

给一个字符串,将其按照单词顺序进行反转。比如说 s 是 "the sky is blue",那么反转就是 "blue is sky the"。

这道题目一看好简单,不就是反转字符串的翻版吗?这种方法有以下两个问题

每个单词长度不一样

空格需要特殊处理

这样一来代码写起来会很繁琐而且容易出错。不如我们先实现一个字符串翻转的方法。


有了这个方法,我们就可以实行下面两种字符串翻转:

整个字符串翻转,"the sky is blue" -> "eulb si yks eht"

每个单词作为一个字符串单独翻转,"eulb si yks eht" -> "blue is sky the"

整体思路有了,我们就可以解决这道问题了

时间复杂度还是 O(n),整体思路和代码简单很多。

总结

在 Swift 中,数组、字符串、集合以及字典是最基本的数据结构,但是围绕这些数据结构的问题层出不穷。而在日常开发中,它们使用起来也非常高效(栈上运行)和安全(无需顾虑线程问题),因为他们都是值类型。

你可能感兴趣的:(iOS面试算法基础(1)-基本数据结构)