一:排序链表

image-20251007214413888

1. 自顶向下归并排序

对链表不断切分,然后使用合并两个有序链表的方式合并

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
class Solution {
public:
ListNode* sortList(ListNode* head) {
return recursion(head, nullptr);
}
ListNode* recursion(ListNode* left, ListNode* right)
{
if (left == nullptr || left->next == nullptr) return left;
if (left->next == right)
{
left->next = nullptr;
return left;
}
ListNode* slow = left, *fast = left;
while (fast != right)
{
slow = slow->next;
fast = fast->next;
if (fast != right) fast = fast->next;
}
ListNode* mid = slow;
ListNode* leftNew = recursion(left, mid);
ListNode* rightNew = recursion(mid, right);
return MergeTwoLists(leftNew, rightNew);
}
ListNode* MergeTwoLists(ListNode* list1, ListNode* list2) {
ListNode* preNode = new ListNode(0); // 哨兵节点
ListNode* cur = preNode;
if (!list1) return list2;
if (!list2) return list1;
while (list1 != nullptr && list2 != nullptr)
{
if (list1->val < list2->val)
{
cur->next = list1;
list1 = list1->next;
}
else
{
cur->next = list2;
list2 = list2->next;
}
cur = cur->next;
}
cur->next = list1 == nullptr ? list2 : list1;
return preNode->next;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
class Solution {
public ListNode sortList(ListNode head) {
return recursion(head, null);
}
public ListNode recursion(ListNode left, ListNode right)
{
if (left == null || left.next == null) return left;
if (left.next == right)
{
left.next = null;
return left;
}
ListNode slow = left, fast = left;
while (fast != right)
{
slow = slow.next;
fast = fast.next;
if (fast != right) fast = fast.next;
}
ListNode mid = slow;
ListNode leftNew = recursion(left, mid);
ListNode rightNew = recursion(mid, right);
return MergeTwoLists(leftNew, rightNew);
}
public ListNode MergeTwoLists(ListNode list1, ListNode list2) {
ListNode preNode = new ListNode(0);
ListNode cur = preNode;
if (list1 == null) return list2;
if (list2 == null) return list1;
while (list1 != null && list2 != null)
{
if (list1.val < list2.val)
{
cur.next = list1;
list1 = list1.next;
}
else
{
cur.next = list2;
list2 = list2.next;
}
cur = cur.next;
}
cur.next = list1 == null ? list2 : list1;
return preNode.next;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class Solution:
def sortList(self, head: Optional[ListNode]) -> Optional[ListNode]:
return self.recursion(head, None)
def recursion(self, left, right):
if (left == None or left.next == None): return left
if (left.next == right):
left.next = None
return left
slow, fast = left, left
while (fast != right):
slow = slow.next
fast = fast.next
if (fast != right): fast = fast.next
mid = slow
leftNew = self.recursion(left, mid)
rightNew = self.recursion(mid, right)
return self.MergeTwoLists(leftNew, rightNew)
def MergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
preNode = ListNode(0) # 没有new
cur = preNode
if not list1: # 这个判断好像不需要,后面的代码实现同样的功能
return list2
if not list2:
return list1
while list1 and list2:
if list1.val < list2.val:
cur.next = list1
list1 = list1.next
else:
cur.next = list2
list2 = list2.next
cur = cur.next
if list1:
cur.next = list1
else:
cur.next = list2
return preNode.next

image-20251007214532164

2. 自底向上归并排序

第一层处理两个节点,将它们断开并排序,第二层结束处理四个节点,其中的两两已经处理好,是有序链表,因此可直接排序,依次迭代

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
class Solution {
public:
ListNode* sortList(ListNode* head) {
if (head == nullptr) return head;
int length = 0;
ListNode* temp = head;
ListNode* pre = new ListNode(0, head);
while (temp != nullptr)
{
++length;
temp = temp->next;
}
for (int sub = 1; sub < length; sub *= 2)
{
ListNode* preCur = pre;
ListNode* cur = pre->next;
while (cur != nullptr)
{
ListNode* node1 = cur;
for (int i = 1; i < sub && cur->next != nullptr; ++i) cur = cur->next;
ListNode* node2 = cur->next;
cur->next = nullptr;
cur = node2;
for (int i = 1; i < sub && cur != nullptr && cur->next !=nullptr; ++i) cur = cur->next;
ListNode* next = nullptr;
if (cur != nullptr)
{
next = cur->next;
cur->next = nullptr;
cur = next;
}
preCur->next = MergeTwoLists(node1, node2);
while (preCur->next != nullptr) preCur = preCur->next;
}
}
return pre->next;
}
ListNode* MergeTwoLists(ListNode* list1, ListNode* list2) {
ListNode* preNode = new ListNode(0); // 哨兵节点
ListNode* cur = preNode;
if (!list1) return list2;
if (!list2) return list1;
while (list1 != nullptr && list2 != nullptr)
{
if (list1->val < list2->val)
{
cur->next = list1;
list1 = list1->next;
}
else
{
cur->next = list2;
list2 = list2->next;
}
cur = cur->next;
}
cur->next = list1 == nullptr ? list2 : list1;
return preNode->next;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
class Solution {
public ListNode sortList(ListNode head) {
if (head == null) return head;
int length = 0;
ListNode temp = head;
ListNode pre = new ListNode(0, head);
while (temp != null)
{
++length;
temp = temp.next;
}
for (int sub = 1; sub < length; sub *= 2)
{
ListNode preCur = pre;
ListNode cur = pre.next;
while (cur != null)
{
ListNode node1 = cur;
for (int i = 1; i < sub && cur.next != null; ++i) cur = cur.next;
ListNode node2 = cur.next;
cur.next = null;
cur = node2;
for (int i = 1; i < sub && cur != null && cur.next !=null; ++i) cur = cur.next;
ListNode next = null;
if (cur != null)
{
next = cur.next;
cur.next = null;
cur = next;
}
preCur.next = MergeTwoLists(node1, node2);
while (preCur.next != null) preCur = preCur.next;
}
}
return pre.next;
}
public ListNode MergeTwoLists(ListNode list1, ListNode list2) {
ListNode preNode = new ListNode(0);
ListNode cur = preNode;
if (list1 == null) return list2;
if (list2 == null) return list1;
while (list1 != null && list2 != null)
{
if (list1.val < list2.val)
{
cur.next = list1;
list1 = list1.next;
}
else
{
cur.next = list2;
list2 = list2.next;
}
cur = cur.next;
}
cur.next = list1 == null ? list2 : list1;
return preNode.next;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
class Solution:
def sortList(self, head: Optional[ListNode]) -> Optional[ListNode]:
if (head == None): return head
length = 0
temp = head
pre = ListNode(0, head)
while (temp != None):
length += 1
temp = temp.next
sub = 1
while (sub < length):
preCur = pre
cur = pre.next
while (cur != None):
node1 = cur
for i in range(1, sub):
if cur.next:
cur = cur.next
else:
break
node2 = cur.next
cur.next = None
cur = node2
for i in range(1, sub):
if cur and cur.next:
cur = cur.next
else:
break
next = None
if (cur != None):
next = cur.next
cur.next = None
cur = next
preCur.next = self.MergeTwoLists(node1, node2)
while (preCur.next != None): preCur = preCur.next
sub *= 2
return pre.next
def MergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
preNode = ListNode(0) # 没有new
cur = preNode
if not list1: # 这个判断好像不需要,后面的代码实现同样的功能
return list2
if not list2:
return list1
while list1 and list2:
if list1.val < list2.val:
cur.next = list1
list1 = list1.next
else:
cur.next = list2
list2 = list2.next
cur = cur.next
if list1:
cur.next = list1
else:
cur.next = list2
return preNode.next

image-20251007214557624

二:LRU缓存

image-20251008130951659

1. 哈希表+双向链表

使用哈希表保存键和双向链表的节点,节点保存键值和前后指针,这样每个操作都为常数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
class LRUCache {
private:
struct DoubleList
{
int key;
int value;
DoubleList* pre;
DoubleList* next;
DoubleList() : key(0), value(0), pre(nullptr), next(nullptr) {}
DoubleList(int _key, int _value) : key(_key), value(_value), pre(nullptr), next(nullptr) {}
};

public:
unordered_map<int, DoubleList*> hashMap;
DoubleList* head;
DoubleList* tail;
int capacity = 0;
int size = 0;
LRUCache(int capacity) {
this->capacity = capacity;
head = new DoubleList();
tail = new DoubleList();
head->next = tail;
tail->pre = head;
}

int get(int key) {
if (hashMap.count(key) == false) return -1;
else
{
DoubleList* cur = hashMap[key];
AddToHead(DeleteNode(cur));
return cur->value;
}
}

void put(int key, int value) {
if (hashMap.count(key) == false)
{
DoubleList* newNode = new DoubleList(key, value);
hashMap[key] = newNode;
AddToHead(newNode);
++size;
if (size > capacity)
{
DoubleList* deleteNode = DeleteNode(tail->pre);
hashMap.erase(deleteNode->key);
delete deleteNode;
--size;
}
} else
{
DoubleList* cur = hashMap[key];
cur->value = value;
AddToHead(DeleteNode(cur));
}
}
DoubleList* DeleteNode(DoubleList* node)
{
node->next->pre = node->pre;
node->pre->next = node->next;
return node;
}
void AddToHead(DoubleList* node)
{
node->pre = head;
node->next = head->next;
head->next = node;
node->next->pre = node;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
class LRUCache {
class DoubleList
{
int key;
int value;
DoubleList pre;
DoubleList next;
public DoubleList() {}
public DoubleList(int _key, int _value) {key = _key; value = _value;}
}
Map<Integer, DoubleList> hashMap = new HashMap<>();
DoubleList head;
DoubleList tail;
int capacity = 0;
int size = 0;

public LRUCache(int capacity) {
this.capacity = capacity;
head = new DoubleList();
tail = new DoubleList();
head.next = tail;
tail.pre = head;
}

public int get(int key) {
if (hashMap.containsKey(key) == false) return -1;
else
{
DoubleList cur = hashMap.get(key);
AddToHead(DeleteNode(cur));
return cur.value;
}
}

public void put(int key, int value) {
if (hashMap.containsKey(key) == false)
{
DoubleList newNode = new DoubleList(key, value);
hashMap.put(key, newNode);
AddToHead(newNode);
++size;
if (size > capacity)
{
DoubleList deleteNode = DeleteNode(tail.pre);
hashMap.remove(deleteNode.key);
--size;
}
} else
{
DoubleList cur = hashMap.get(key);
cur.value = value;
AddToHead(DeleteNode(cur));
}
}
public DoubleList DeleteNode(DoubleList node)
{
node.next.pre = node.pre;
node.pre.next = node.next;
return node;
}
public void AddToHead(DoubleList node)
{
node.pre = head;
node.next = head.next;
head.next = node;
node.next.pre = node;
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
class LRUCache:
def __init__(self, capacity: int):
self.capacity = capacity
self.size = 0
self.hashMap = dict()
self.head = DoubleList()
self.tail = DoubleList()
self.head.next = self.tail
self.tail.prev = self.head


def get(self, key: int) -> int:
if (key not in self.hashMap): return -1
else:
cur = self.hashMap[key]
self.AddToHead(self.DeleteNode(cur))
return cur.value

def put(self, key: int, value: int) -> None:
if (key not in self.hashMap):
newNode = DoubleList(key, value)
self.hashMap[key] = newNode
self.AddToHead(newNode)
self.size += 1
if (self.size > self.capacity):
deleteNode = self.DeleteNode(self.tail.pre)
self.hashMap.pop(deleteNode.key)
self.size -= 1
else:
cur = self.hashMap[key]
cur.value = value
self.AddToHead(self.DeleteNode(cur))

def DeleteNode(self, node):
node.next.pre = node.pre
node.pre.next = node.next
return node
def AddToHead(self, node):
node.pre = self.head
node.next = self.head.next
self.head.next = node
node.next.pre = node

class DoubleList:
def __init__(self, key = 0, value = 0):
self.key = key
self.value = value
self.prev = None
self.next = None

image-20251008135456071

三:二叉树的层序遍历

image-20251008142237623

1. 广度优先搜索

用队列表示每一层,逐层遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> result;
if (root == nullptr) return result;
queue<TreeNode*> queueTree;
queueTree.push(root);
while (queueTree.empty() == false)
{
int size = queueTree.size();
result.emplace_back(vector<int>());
for (int i = 0; i < size; ++i)
{
TreeNode* newNode = queueTree.front();
queueTree.pop();
result.back().emplace_back(newNode->val);
if (newNode->left) queueTree.push(newNode->left);
if (newNode->right) queueTree.push(newNode->right);
}
}
return result;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
if (root == null) return result;
Queue<TreeNode> queueTree = new LinkedList<>();
queueTree.offer(root);
while (queueTree.isEmpty() == false)
{
int size = queueTree.size();
List<Integer> level = new ArrayList<>();
for (int i = 0; i < size; ++i)
{
TreeNode newNode = queueTree.poll();
level.add(newNode.val);
if (newNode.left != null) queueTree.offer(newNode.left);
if (newNode.right != null) queueTree.offer(newNode.right);
}
result.add(level);
}
return result;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution:
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
result = []
if (root == None): return result
queueTree = deque([root])
while (queueTree):
size = len(queueTree)
level = []
for _ in range(size):
newNode = queueTree.popleft()
level.append(newNode.val)
if (newNode.left != None): queueTree.append(newNode.left)
if (newNode.right != None): queueTree.append(newNode.right)
result.append(level)
return result

image-20251008142309731

四:验证二叉搜索树

image-20251008150751550

1. 递归

参考二叉树的中序遍历的递归写法,这里多了对数据大小的判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public:
bool isValidBST(TreeNode* root) {
return recursion(root, LONG_MIN, LONG_MAX);
}
bool recursion(TreeNode* node, long long min, long long max)
{
if (node == nullptr) return true;
if (node->val <= min || node->val >= max) return false;
bool flagLeft = recursion(node->left, min, node->val);
bool flagRight = recursion(node->right, node->val, max);
return flagLeft && flagRight;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
public boolean isValidBST(TreeNode root) {
return recursion(root, Long.MIN_VALUE, Long.MAX_VALUE);
}
public boolean recursion(TreeNode node, long min, long max)
{
if (node == null) return true;
if (node.val <= min || node.val >= max) return false;
boolean flagLeft = recursion(node.left, min, node.val);
boolean flagRight = recursion(node.right, node.val, max);
return flagLeft && flagRight;
}
}
1
2
3
4
5
6
7
8
9
class Solution:
def isValidBST(self, root: Optional[TreeNode]) -> bool:
def recursion(node, min, max):
if (node == None): return True
if (node.val <= min or node.val >= max): return False
flagLeft = recursion(node.left, min, node.val)
flagRight = recursion(node.right, node.val, max)
return flagLeft and flagRight
return recursion(root, float('-inf'), float('inf'))

image-20251008150829685

2. 中序遍历

参考二叉树的中序遍历的迭代写法,这里多了对数据大小的判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
public:
bool isValidBST(TreeNode* root) {
stack<TreeNode*> treeStack;
long long min = (long long)INT_MIN - 1;
while (root != nullptr || !treeStack.empty()) // 需要保证栈中的内容处理完毕
{
while (root != nullptr)
{
treeStack.push(root); // 入栈
root = root->left;
}
root = treeStack.top(); // 栈顶
treeStack.pop(); // 拿到数据出栈
if (root -> val <= min) return false;
min = root -> val;
root = root->right;
}
return true;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution {
public boolean isValidBST(TreeNode root) {
Deque<TreeNode> treeDeque = new ArrayDeque<TreeNode>();
double min = -Double.MAX_VALUE - 1;
while (root != null || !treeDeque.isEmpty()) // 使用isEmpty
{
while (root != null)
{
treeDeque.push(root);
root = root.left;
}
root = treeDeque.pop();
if (root.val <= min) return false;
min = root.val;
root = root.right;
}
return true;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution:
def isValidBST(self, root: Optional[TreeNode]) -> bool:
treeStack = []
min = float('-inf')
while root is not None or treeStack:
while root is not None:
treeStack.append(root)
root = root.left
root = treeStack.pop()
if (root.val <= min): return False
min = root.val
root = root.right
return True

image-20251008150838767

五:二叉搜索树中第 K 小的元素

image-20251008155023481

1. 中序遍历

利用中序遍历得到有序数组,找到数组中的第K个元素即可。迭代用栈管理,栈弹出的顺序就是有序列表,因此第K个就是需要的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
public:
int kthSmallest(TreeNode* root, int k) {
stack<TreeNode*> treeStack;
while (root != nullptr || !treeStack.empty())
{
while (root != nullptr)
{
treeStack.push(root);
root = root->left;
}
root = treeStack.top();
treeStack.pop(); // 第一个出栈的为最小元素,出栈k次即可得到结果
--k;
if (k == 0) break;
root = root->right;
}
return root->val;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution {
public int kthSmallest(TreeNode root, int k) {
Deque<TreeNode> treeDeque = new ArrayDeque<TreeNode>();
double min = -Double.MAX_VALUE - 1;
while (root != null || !treeDeque.isEmpty()) // 使用isEmpty
{
while (root != null)
{
treeDeque.push(root);
root = root.left;
}
root = treeDeque.pop();
--k;
if (k == 0) break;
root = root.right;
}
return root.val;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
class Solution:
def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:
treeStack = []
while root is not None or treeStack:
while root is not None:
treeStack.append(root)
root = root.left
root = treeStack.pop()
k -= 1
if (k == 0): break
root = root.right
return root.val

image-20251008155214143

2. 记录子树的节点

把每个节点的左右子树的节点数量记录,此时只需要判断k与子树节点数量的大小,因为左子树一定小于当前节点,右子树大于当前节点。适用于频繁寻找k值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Solution {
public:
unordered_map<TreeNode*, int> hashMap;
TreeNode* root;
int kthSmallest(TreeNode* root, int k) {
this->root = root;
CountNum(root);
return SearchTarget(k);
}
int CountNum(TreeNode* node)
{
if (node == nullptr) return 0;
hashMap[node] = 1 + CountNum(node->left) + CountNum(node->right);
return hashMap[node];
}
int GetNum(TreeNode* node)
{
if (node != nullptr && hashMap.count(node)) return hashMap[node];
else return 0;
}
int SearchTarget(int k)
{
TreeNode* node = root;
while (node != nullptr)
{
int leftNum = GetNum(node->left);
if (leftNum < k - 1)
{
node = node->right;
k -= leftNum + 1;
} else if (leftNum > k - 1) node = node->left;
else break;
}
return node->val;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class Solution {
public Map<TreeNode, Integer> hashMap = new HashMap<>();
public TreeNode root;
public int kthSmallest(TreeNode root, int k) {
this.root = root;
CountNum(root);
return SearchTarget(k);
}
public int CountNum(TreeNode node)
{
if (node == null) return 0;
hashMap.put(node, 1 + CountNum(node.left) + CountNum(node.right));
return hashMap.get(node);
}
public int GetNum(TreeNode node)
{
if (node != null && hashMap.containsKey(node)) return hashMap.get(node);
else return 0;
}
public int SearchTarget(int k)
{
TreeNode node = root;
while (node != null)
{
int leftNum = GetNum(node.left);
if (leftNum < k - 1)
{
node = node.right;
k -= leftNum + 1;
} else if (leftNum > k - 1) node = node.left;
else break;
}
return node.val;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution:
def kthSmallest(self, root: TreeNode, k: int) -> int:
self.hashMap = {}
self.root = root
self.CountNum(self.root)
return self.SearchTarget(k)
def CountNum(self, node):
if (node == None): return 0
self.hashMap[node] = 1 + self.CountNum(node.left) + self.CountNum(node.right)
return self.hashMap[node]
def GetNum(self, node):
if (node != None and node in self.hashMap): return self.hashMap[node]
else: return 0
def SearchTarget(self, k):
node = self.root
while (node != None):
leftNum = self.GetNum(node.left)
if (leftNum < k - 1):
node = node.right
k -= leftNum + 1
elif (leftNum > k - 1): node = node.left
else: break
return node.val

image-20251008155259285

3. 平衡二叉搜索树

官方给的题解太长了,使用了经典的AVL树数据结构,并添加了一些常用的操作,没必要,简化一下吧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
struct Node {
int val;
Node * parent;
Node * left;
Node * right;
int size;
int height;
Node(int val, Node * parent) {
this->val = val;
this->parent = parent;
this->left = nullptr;
this->right = nullptr;
this->height = 0;
this->size = 1;
}
};

class AVL {
public:
Node * root;
AVL(vector<int> & vals) {
if (!vals.empty()) {
root = build(vals, 0, vals.size() - 1, nullptr);
}
}
Node * build(vector<int> & vals, int l, int r, Node * parent) {
int m = (l + r) >> 1;
Node * node = new Node(vals[m], parent);
if (l <= m - 1) {
node->left = build(vals, l, m - 1, node);
}
if (m + 1 <= r) {
node->right = build(vals, m + 1, r, node);
}
recompute(node);
return node;
}
void recompute(Node * node) {
node->height = 1 + max(getHeight(node->left), getHeight(node->right));
node->size = 1 + getSize(node->left) + getSize(node->right);
}
static int getHeight(Node * node) {
return node != nullptr ? node->height : 0;
}
static int getSize(Node * node) {
return node != nullptr ? node->size : 0;
}
int kthSmallest(int k) {
Node * node = root;
while (node != nullptr) {
int left = getSize(node->left);
if (left < k - 1) {
node = node->right;
k -= left + 1;
} else if (left == k - 1) {
break;
} else {
node = node->left;
}
}
return node->val;
}
};

class Solution {
public:
int kthSmallest(TreeNode* root, int k) {
vector<int> inorderList;
inorder(root, inorderList);
AVL avl(inorderList);
return avl.kthSmallest(k);
}
void inorder(TreeNode * node, vector<int> & inorderList) {
if (node->left != nullptr) {
inorder(node->left, inorderList);
}
inorderList.push_back(node->val);
if (node->right != nullptr) {
inorder(node->right, inorderList);
}
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
class Node {
int val;
Node parent;
Node left;
Node right;
int size;
int height;

Node(int val, Node parent) {
this.val = val;
this.parent = parent;
this.left = null;
this.right = null;
this.height = 0;
this.size = 1;
}
}

class AVL {
Node root;

AVL(List<Integer> vals) {
if (!vals.isEmpty()) {
root = build(vals, 0, vals.size() - 1, null);
}
}

Node build(List<Integer> vals, int l, int r, Node parent) {
if (l > r) {
return null;
}

int m = l + (r - l) / 2;
Node node = new Node(vals.get(m), parent);

node.left = build(vals, l, m - 1, node);
node.right = build(vals, m + 1, r, node);

recompute(node);
return node;
}

void recompute(Node node) {
if (node == null) return;
node.height = 1 + Math.max(getHeight(node.left), getHeight(node.right));
node.size = 1 + getSize(node.left) + getSize(node.right);
}

static int getHeight(Node node) {
return node != null ? node.height : 0;
}

static int getSize(Node node) {
return node != null ? node.size : 0;
}

int kthSmallest(int k) {
Node node = root;
while (node != null) {
int left = getSize(node.left);
if (left < k - 1) {
node = node.right;
k -= left + 1;
} else if (left == k - 1) {
break;
} else {
node = node.left;
}
}
return node.val;
}
}

class Solution {
public int kthSmallest(TreeNode root, int k) {
List<Integer> inorderList = new ArrayList<>();
inorder(root, inorderList);

if (inorderList.isEmpty() || k <= 0 || k > inorderList.size()) {
return -1;
}

AVL avl = new AVL(inorderList);
return avl.kthSmallest(k);
}

void inorder(TreeNode node, List<Integer> inorderList) {
if (node == null) {
return;
}
inorder(node.left, inorderList);
inorderList.add(node.val);
inorder(node.right, inorderList);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
class Node:
def __init__(self, val: int, parent: Optional['Node'] = None):
self.val = val
self.parent = parent
self.left = None
self.right = None
self.height = 0
self.size = 1

class AVL:
def __init__(self, vals: List[int]):
self.root: Optional[Node] = None
if vals:
self.root = self.build(vals, 0, len(vals) - 1, None)

def build(self, vals: List[int], l: int, r: int, parent: Optional[Node]) -> Optional[Node]:
if l > r:
return None

m = (l + r) // 2
node = Node(vals[m], parent)

node.left = self.build(vals, l, m - 1, node)
node.right = self.build(vals, m + 1, r, node)

self.recompute(node)
return node

def recompute(self, node: Node):
if node is None:
return

left_height = AVL.get_height(node.left)
right_height = AVL.get_height(node.right)

node.height = 1 + max(left_height, right_height)
node.size = 1 + AVL.get_size(node.left) + AVL.get_size(node.right)

@staticmethod
def get_height(node: Optional[Node]) -> int:
return node.height if node else 0

@staticmethod
def get_size(node: Optional[Node]) -> int:
return node.size if node else 0

def kthSmallest(self, k: int) -> int:
node = self.root
while node:
left_size = AVL.get_size(node.left)

if left_size < k - 1:
k -= left_size + 1
node = node.right
elif left_size == k - 1:
return node.val
else:
node = node.left

return -1

class Solution:
def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:
inorder_list: List[int] = []
self._inorder(root, inorder_list)

if not inorder_list or k <= 0 or k > len(inorder_list):
return -1

avl = AVL(inorder_list)
return avl.kthSmallest(k)

def _inorder(self, node: Optional[TreeNode], inorder_list: List[int]):
if node is None:
return

self._inorder(node.left, inorder_list)
inorder_list.append(node.val)
self._inorder(node.right, inorder_list)

image-20251008155313141