Bài toán
Link đến bài toán: 501. Find Mode in Binary Search Tree
Phân tích
Bài này có hai cách giải, hoặc là dùng hashmap hoặc dựa vào tính chất của cây nhị phân tìm kiếm và sử dụng inorder traversal.
Với cách dùng hashmap thì ta sẽ duyệt qua cây và đếm số lần xuất hiện của các giá trị, sau đó tìm các giá trị có số lần xuất hiện nhiều nhất là được.
Còn với cách dùng inorder traversal, ta để ý rằng đề bài cho ta một cây BST.
Tính chất của cây BST đảm bảo rằng, khi ta duyệt cây bằng inorder traversal (BFS/DFS), ta sẽ duyệt các giá trị theo thứ tự được sắp xếp (trong bài này là tăng dần).
Từ đây có thể giải bằng cách convert cây sang một mảng và duyệt mảng để tìm các giá trị có số lần xuất hiện nhiều nhất, hoặc xử lý thẳng trên cây khi duyệt.
Giải thuật
Giải thuật 1: Dùng hashmap
- Khởi tạo một
hashmapđể đếm số lần xuất hiện của các giá trị. - Duyệt cây và đếm số lần xuất hiện của các giá trị.
- Tìm các giá trị có số lần xuất hiện nhiều nhất.
- Trả về kết quả.
Này dễ nên mọi người tự cài đặt nhớ /ᐠ - ˕ -マ Ⳋ
Giải thuật 2: DFS
- Khởi tạo một biến
maxStreakđể lưu giá trị lớn nhất củacurStreak(số lần xuất hiện nhiều nhất của một giá trị). - Khởi tạo một biến
curStreakđể lưu số lần xuất hiện của giá trị hiện tại. - Khởi tạo một biến
lastNumđể lưu giá trị của node trước đó. - Khởi tạo một mảng
resđể lưu kết quả. - Khởi tạo một hàm
dfsđể duyệt cây:- Nếu node hiện tại là
nilthì thoát. - Gọi đệ quy
dfsvới node con bên trái. - Nếu giá trị của node hiện tại bằng với
lastNum:- Tăng
curStreaklên 1.
- Tăng
- Nếu không:
- Gán
curStreakbằng 1. - Gán
lastNumbằng giá trị của node hiện tại.
- Gán
- Nếu
curStreak>maxStreak:- Gán
maxStreak=curStreak. - Gán
resbằng một mảng chứa giá trị của node hiện tại.
- Gán
- Nếu
curStreak==maxStreak:- Thêm giá trị của node hiện tại vào
res.
- Thêm giá trị của node hiện tại vào
- Gọi đệ quy
dfsvới node con bên phải.
- Nếu node hiện tại là
func findMode(root *TreeNode) []int {
maxStreak, curStreak, lastNum := 0, 0, 0
res := make([]int, 0)
var dfs func(root *TreeNode)
dfs = func(root *TreeNode) {
if root == nil {
return
}
dfs(root.Left)
if root.Val == lastNum {
curStreak++
} else {
curStreak = 1
lastNum = root.Val
}
if curStreak > maxStreak {
maxStreak = curStreak
res = []int{root.Val}
} else if curStreak == maxStreak {
res = append(res, root.Val)
}
dfs(root.Right)
}
dfs(root)
return res
}