Swift 演算法實戰之路(二)

發表於2016-05-24

 

上次講解了基本的語法和一些Swift的小技巧。今天我們來看幾個最基本的資料結構:陣列,字串,集合和字典。

陣列

陣列是最基本的資料結構。Swift中改變了以前Objective-C時代NSMutableArray和NSArray分開的做法,統一到了Array唯一的資料結構。下面是最基本的一些實現。

不要小看這些簡單的操作:陣列可以依靠它們實現更多的資料結構。Swift雖然不像Java中有現成的佇列和棧,但我們完全可以用陣列配合最簡單的操作實現這些資料結構,下面就是用陣列實現棧的示例程式碼。

集合和字典

這兩個資料結構經常使用的原因在於,查詢資料的時間複雜度為O(1)。這兩個在實戰中經常與陣列配合使用,請看下面這道題:

給一個整型陣列和一個目標值,判斷陣列中是否有兩個數字之和等於目標值

這道題是傳說中經典的2Sum,我們已經有一個陣列記為nums,也有一個目標值記為target,最後要返回一個Bool值。
最粗暴的方法就是每次選中一個數,然後遍歷整個陣列,判斷是否有另一個數使兩者之和為target。這種做法時間複雜度為O(n^2)。
採用集合可以優化時間複雜度。在遍歷陣列的過程中,用集合每次儲存當前值。假如集合中已經有了目標值減去當前值,則證明在之前的遍歷中一定有一個數與當前值之和等於目標值。這種做法時間複雜度為O(n),程式碼如下。

如果把題目稍微修改下,變為

給定一個整型陣列中有且僅有兩個數字之和等於目標值,求兩個數字在陣列中的序號

思路與上題基本類似,但是為了方便拿到序列號,我們採用字典,時間複雜度依然是O(n)。程式碼如下。

字串

字串在演算法實戰中極其常見。首先還是列舉一下字串的通常用法。

下面是本篇的精華所在,我們來一起看一道以前的Google面試題。

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?

這道題目一看好簡單,不就是翻轉字串的翻版嗎?這種方法有以下兩個問題

  • 每個單詞長度不一樣
  • 空格需要特殊處理

這樣一來程式碼寫起來會很繁瑣而且容易出錯。不如我們先實現一個字串翻轉的方法。

有了這個方法,我們就可以實行下面兩種字串翻轉:

  • 整個字串翻轉,”the sky is blue” -> “eulb si yks eht”
  • 每個單詞作為一個字串單獨翻轉,”eulb si yks eht” -> “blue is sky the”

整體思路有了,我們就可以解決這道問題了

時間複雜度還是O(n),整體思路和程式碼簡單很多。

總結

Swift中陣列、字串、集合以及字典是最基本的資料結構,但是圍繞這些資料結構的問題層出不窮。幸運的是解決方法也並不是千變萬化、高深莫測,大家做好相應的積累即可。下期我們講連結串列、棧、佇列這三種資料結構。

相關文章