501. 1.二叉搜索树中的众数
- 题目描述:
给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。
假定 BST 有如下定义:
结点左子树中所含结点的值小于等于当前结点的值 结点右子树中所含结点的值大于等于当前结点的值 左子树和右子树都是二叉搜索树
- 示例:
例如:
给定 BST [1,null,2,2],
1
\
2
/
2
返回[2].
- 思路一:直接暴力 HashMap
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
Map<Integer, Integer> map;
public int[] findMode(TreeNode root) {
if(root == null){
return new int[0];
}
map = new HashMap<>();
dfs(root);
int max = map.get(root.val);
for(Integer num : map.values()){
if(max < num){
max = num;
}
}
List<Integer> list = new ArrayList<>();
for(int a : map.keySet()){
if(map.get(a) == max){
list.add(a);
}
}
int[] res = new int[list.size()];
for(int i = 0; i < res.length; i++){
res[i] = list.get(i);
}
return res;
}
public void dfs(TreeNode root){
if(root == null){
return;
}
map.put(root.val, map.getOrDefault(root.val, 0) + 1);
dfs(root.left);
dfs(root.right);
}
}
- 思路二:利用中序遍历为升序的性质
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
List<Integer> mList = new ArrayList<>();
int curent = 0;//表示当前节点的值
int count = 0;//表示当前节点的数量
int maxCount = 0;//最大的重复数量
public int[] findMode(TreeNode root) {
inOrderTraversal(root);
int[] res = new int[mList.size()];
//把集合list转化为数组
for (int i = 0; i < mList.size(); i++) {
res[i] = mList.get(i);
}
return res;
}
//递归方式
public void inOrderTraversal(TreeNode node) {
//终止条件判断
if (node == null)
return;
//遍历左子树
inOrderTraversal(node.left);
//下面是对当前节点的一些逻辑操作
int nodeValue = node.val;
if (nodeValue == curent) {
//如果节点值等于curent,count就加1
count++;
} else {
//否则,就表示遇到了一个新的值,curent和count都要
//重新赋值
curent = nodeValue;
count = 1;
}
if (count == maxCount) {
//如果count == maxCount,就把当前节点加入到集合中
mList.add(nodeValue);
} else if (count > maxCount) {
//否则,当前节点的值重复量是最多的,直接把list清空,然后
//把当前节点的值加入到集合中
mList.clear();
mList.add(nodeValue);
maxCount = count;
}
//遍历右子树
inOrderTraversal(node.right);
}
}
2. 初级算法:删除排序数组中的重复项
给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
示例 1:
给定数组 nums = [1,1,2],
函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。
你不需要考虑数组中超出新长度后面的元素。
示例 2:
给定 nums = [0,0,1,1,1,2,2,3,3,4],
函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。
你不需要考虑数组中超出新长度后面的元素。
- 思路:双指针法,定义一个index指针,和一个cur指针,如果有重复的情况那么分开讨论,看代码就可以明白
class Solution {
public int removeDuplicates(int[] nums) {
//判断边界情况
if(nums.length <= 1){
return nums.length;
}
int index = 0;
int cur = 1;
if((nums[index] == nums[cur]) && (nums.length == 2)){
return cur;
}
while(cur < nums.length){
if(nums[index] == nums[cur]){
cur++;
}else if((nums[index] != nums[cur]) && (cur - index == 1)){
cur++;
index++;
}else{
nums[++index] = nums[cur];
}
}
return index + 1;
}
}