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
sIdxvàtIdxlà index của chuỗisvàt. - Khởi tạo
sSkipvàtSkiplà số lượng ký tự cần bỏ qua của chuỗisvàt. Ban đầu,sSkipvàtSkipbằng 0. - Lặp chừng nào
sIdx >= 0 || tIdx >= 0:- Với chuỗi s:
- Nếu
s[sIdx] == '#', tăngsSkiplê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
sIdxvà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é.