Leetcode 30 天挑戰, Week 2 Day 7, Perform String Shifts, in Swift
資料結構或演算法: String
Math
這一題好像是新的,還沒有原先題目頁面。
思維
這題應該算是數學歸納的問題,步驟說明、演算法有更好解或是複雜度分析有問題的話都請留言告訴我。
步驟
- 算出最終移動的方向(概念和前一天的題目相同,題目筆記之後再補)
- 往左就 -1 ,往右就 +1
- 總部數是 0 就直接回傳
- 因為移動超過字串長度後就會開始循環做同樣的事情,於是除以字串長度取得餘數
- 根據分析會發現 (往左 + 字串長度) 會和 往右 會有同樣的效果,因此如果是負值的話將它加上字串長度
- 接著一個一個把最後一個字元往前移動到前面
- 生成字串物件回傳
程式碼
class Solution {
func stringShift(_ s: String, _ shift: [[Int]]) -> String {
if s.count <= 1 { return s }
var moves = 0
// 取得算出所有移動後的最終步數
for pair in shift {
var direction = pair[0]
var steps = pair[1]
switch direction {
case 0: moves -= steps
case 1: moves += steps
default: break
}
}
// 為零就直接回傳
if moves == 0 { return s }
// 必要之惡
var characters = Array(s)
var length = characters.count
// 把步數正規化到 -length + 1 到 length - 1 之間
moves %= length
// 若步數為負值,把它轉換成相對應的正值
if moves < 0 {
moves += length
}
// 移動...移動...移動...
while moves > 0 && moves <= length {
characters.insert(characters.removeLast(), at: 0)
moves -= 1
}
return String(characters)
}
}
高階函數
如果熱愛高階函數的話,可以把算出最終步數的地方改成這樣
var moves = shift.reduce(0) { $0 + ($1[0] == 0 ? -1 : 1 ) * $1[1] }
想要把程式碼整體變短還有更激進的做法,不過會大大降低程式碼的可讀性在這邊就不繼續做了。
複雜度分析
- 時間複雜度: O(max(s.length, shift.length))
- 全部執行都是單層迴圈,因此就看誰的數量比較多。
- 空間複雜度: O(s.length)
- 轉成 characters 應該是必要之惡(翻白眼)
結果
寫的時候樣本數不足因此無法知道在幾趴的地方
Runtime: 8 ms
Memory Usage: 21.6 MB
改成高階函數的運行結果如下(是壞掉了?)
自己的 Testcase
直接貼到他提供的框框裡面即可
"abc"
[[0,1],[1,2]]
"abcdefg"
[[1,1],[1,1],[0,2],[1,3]]
"wpdhhcj"
[[0,7],[1,7],[1,0],[1,3],[0,3],[0,6],[1,2]]
Author And Source
この問題について(Leetcode 30 天挑戰, Week 2 Day 7, Perform String Shifts, in Swift), 我々は、より多くの情報をここで見つけました https://qiita.com/vc7/items/a861023d20c26ea937d0著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .