Bài toán
Link đến bài toán: 844. Backspace String Compare
Phân tích
Nếu giải theo constraint time complexity là O(n)
và space complexity là O(n)
, thì bài này khá đơn giản.
Ta có thể tạo chuỗi mới từ chuỗi ban đầu rồi so sánh hai chuỗi này với nhau.
Hoặc ta có thể dùng stack.
Tuy nhiên, để giải theo constraint time complexity là O(n)
và space complexity là O(1)
như yêu cầu của follow-up thì sẽ hơi khó hơn một tí.
Ta sẽ duyệt chuỗi từ cuối lên đầu, và dùng một biến skip
để đếm số lượng ký tự cần bỏ qua.
Nếu gặp ký tự #
, ta sẽ tăng skip
lên 1. Nếu gặp ký tự khác #
và skip
khác 0,
ta sẽ bỏ qua ký tự đó (tức là giảm index và trừ skip đi 1).
Giải thuật
Giải theo constraint time complexity là O(n)
và space complexity là O(1)
- Khởi tạo
sIdx
vàtIdx
là index của chuỗis
vàt
. - Khởi tạo
sSkip
vàtSkip
là số lượng ký tự cần bỏ qua của chuỗis
vàt
. Ban đầu,sSkip
vàtSkip
bằng 0. - Lặp chừng nào
sIdx >= 0 || tIdx >= 0
:- Với chuỗi s:
- Nếu
s[sIdx] == '#'
, tăngsSkip
lên 1 và giảmsIdx
đi 1. - Nếu
sSkip > 0
, giảmsSkip
đi 1 và giảmsIdx
đi 1. - Nếu không, thoát khỏi vòng lặp.
- Nếu
- Tương tự với chuỗi
t
. - Nếu
sIdx >= 0 && tIdx >= 0 && s[sIdx] != t[tIdx]
, trả vềfalse
. (Vì hai kí tự tại vị trí này không bằng nhau) - Nếu
(sIdx >= 0) != (tIdx >= 0)
, trả vềfalse
. (Vì hai chuỗi này không bằng nhau) - Giảm
sIdx
vàtIdx
đi 1.
- Với chuỗi s:
- Trả về
true
.
func backspaceCompare(s string, t string) bool {
sIdx, tIdx := len(s)-1, len(t)-1
sSkip, tSkip := 0, 0
for sIdx >= 0 || tIdx >= 0 {
for sIdx >= 0 {
if s[sIdx] == '#' {
sSkip++
sIdx--
} else if sSkip > 0 {
sSkip--
sIdx--
} else {
break
}
}
for tIdx >= 0 {
if t[tIdx] == '#' {
tSkip++
tIdx--
} else if tSkip > 0 {
tSkip--
tIdx--
} else {
break
}
}
if sIdx >= 0 && tIdx >= 0 && s[sIdx] != t[tIdx] {
return false
}
if (sIdx >= 0) != (tIdx >= 0) {
return false
}
sIdx--
tIdx--
}
return true
}
Cách giải dùng stack hoặc tạo chuỗi mới khá dễ nên độc giả tự cài đặt nhé.