38. Count and Say
The count-and-say sequence is the sequence of integers with the first five terms as following:
1. 1 2. 11 3. 21 4. 1211 5. 111221
1
is read off as"one 1"
or11
.
11
is read off as"two 1s"
or21
.
21
is read off as"one 2, then one 1"
or1211
.Given an integer n where 1 ≤ n ≤ 30, generate the nth term of the count-and-say sequence.
Note: Each term of the sequence of integers will be represented as a string.
With iteration:
How to reduce 3 kinds of situation to one solution?
class Solution {
func countAndSay(_ n: Int) -> String {
var ans = ["1"]
var temp: [String], j: Int
for _ in 1..<n{
// from the beginning 1 to what we what
j = 1
temp = []
for i in 1..<ans.count{
if ans[i - 1] == ans[i]{
j += 1
// Situation one: the current is equal to the previous ( util the last )
}
else{
temp.append(String(j))
temp.append(ans[i-1])
// Situation two: the current is not equal to the previous ( util the last )
j = 1
}
}
// Situation three: the last value
temp.append(String(j))
temp.append(ans.last!)
ans = temp
print(ans.reduce("", +))
}
return ans.reduce("", +)
}
}
With Recursion, which is a little leaner.
class Solution {
func countAndSay(_ n: Int) -> String {
if n == 1 {
return "1"
}
let str = countAndSay(n-1)
let arr = Array(str).map{Int(String($0))}
var last = arr[0]!
var temp : [(count: Int, val: Int)] = [(1, last)]
for num in arr[1...]{
if last == num{
var final = temp.last!
final.count += 1
temp.removeLast()
temp.append(final)
}
else{
temp += [(1, num!)]
}
last = num!
}
var result = ""
for key in temp{
result += "\(key.0)\(key.1)"
}
return result
}
}
How to go on doing some improvement?