问题1,合并两个list
问题描述
给定两个list集合,集合存放无序、重复的整数,求并集
输入描述:
输入两个整数list
输出描述:
输出他们的并集
示例
示例1
输入
4,2,1
1,2,3
输出
1,2,3,4
解决思路
分析
需要明确list中包含重复的元素,而且是无序的。
方法
- 通过java list自带的方法解决,时间复杂度无法自控
- 通过两个下标指针的移动解决
代码实现
// 思路1实现
public class Main{
public List<Integer> merge (List<Integer> a, List<Integer> b) {
List<Integer> result = new ArrayList<>(a.size()+ b.size());
result.addAll(a);
result.removeAll(b);
result.addAll(b);
return result;
}
}
// 思路2实现
public class Main {
public List<Integer> merge (List<Integer> a, List<Integer> b) {
// sort方法本身用到arrays.sort方法
a.sort(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
if (o1 > o2) {
return 1;
}
return -1;
}
});
b.sort(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
if (o1 > o2) {
return 1;
}
return -1;
}
});
List<Integer> result = new ArrayList<>(a.size()+ b.size());
if (a.size() > b.size()) {
List<Integer> temp = a;
a = b;
b = temp;
}
int i = 0;
int j = 0;
while (i < a.size() && j < b.size()) {
if (a.get(i).equals(b.get(j))) {
if (i >= 1 && !a.get(i).equals(a.get(i - 1)) ) {
result.add(a.get(i));
}
i++;
j++;
continue;
}
while (a.get(i) < b.get(j) && i < a.size()) {
result.add(a.get(i));
i++;
continue;
}
while (a.get(i) > b.get(j) && j < b.size()) {
result.add(b.get(j));
j++;
continue;
}
}
while (j < b.size()) {
result.add(b.get(j));
j++;
continue;
}
return result;
}
}
问题2,校验IP地址
问题描述
输入一个IP地址的字符数组,判断这个IP地址是否有效
输入描述:
输入一个IP地址的字符数组
输出描述:
输出是否是有效IP
示例
示例1
输入
10.255.1.1
输出
true
解决思路
分析
分析校验的内容:
- 判断‘.’的个数是否正确
- 判断每一段的范围是否是[0,255]
方法
- 通过自定义实现字符数组转int来实现判断每一段的数字范围
代码实现
public class IP地址校验 {
// 校验内容
// ip有四个段,也就是说有三个.
// 每个段的范围 0 - 255
public boolean isIP (char[] arr) {
int strat = 0;
int end = 0;
int count = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] >= '0' && arr[i] <= '9') {
end++;
continue;
}
if (arr[i] >= '.' && pareInt(arr, strat, end) <= 255) {
strat = i + 1;
end = strat;
count++;
continue;
}
return false;
}
if (count != 3) {
return false;
}
return true;
}
private int pareInt (char[] arr, int start, int end) {
int result = 0;
int temp = 1;
for (int i = end - 1; i >= start; i--) {
result += (arr[i] - '0') * temp;
temp *= 10;
}
return result;
}
}
问题3,查找二叉搜索树的第二小节点
问题描述
输入是一棵二叉搜索树的跟节点,输出第二小节点的值或节点(要求:不能使用额外的空间)
输入描述:
输入一个二叉搜索树的跟节点
输出描述:
输出第二小节点的值或节点
示例
示例1
输入 (这里直接展示了树的图片,实际输入是跟节点)
输出
3
解决思路
分析
分析第二小节点的情况,这里的第二小只能存在两种情况:
- 第二小节点是根节点,说明最小的节点是此跟节点的左节点
- 第二小节点是左节点,说明这个左节点位于某个根节点的右子树上,这样最小的节点即为该跟节点
方法
- 在不申请任何额外空间的情况下查找
- 使用额外的空间,来自力扣的230题(下文有地址)1
代码实现
// 方法一
// PS:博主没有经过严格的复测,代码有问题,请指出
public class 二叉搜索 {
public TreeNode getSecond (TreeNode root) {
TreeNode temp = root;
TreeNode parNode = root;
int min = root.val;
while (temp != null) {
min = Math.min(min, temp.val);
// 左右子树都包含的情况
if (temp.left == null && temp.right == null) {
if (temp.val == parNode.val) {
return null;
}
// 区分第二小的节点是跟节点,还是左节点的情况
// 左节点:左节点的值<他的父节点的值;左节点的值>最小值
if (temp.val < parNode.val && temp.val > min) {
return temp;
} else {
return parNode;
}
}
// 如果碰到了节点的左子树为空,继续查找他的右子树,此时的根节点的值是最小值
if (temp.left == null && temp.right != null) {
parNode = temp;
temp = temp.right;
continue;
}
parNode = temp;
temp = temp.left;
}
return temp;
}
}
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {
}
TreeNode(int val) {
this.val = val;
}
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
// 力扣原题是:230. 二叉搜索树中第K小的元素,需要申请额外的空间
// 这里提供两种思路
// 1、利用中序遍历的特点,二叉搜索树的中序遍历,是有序的数组
// 2、利用队列实现迭代查找,避免第一种方法的全部遍历
public class 二叉搜索树第k小节点 {
// 1、通过二叉搜索树中序遍历的特点
// 二叉搜索树,中序遍历后是一个有顺序的数组
// 第k小的元素就是排好序数组的第k-1个元素
public ArrayList<Integer> inorder(TreeNode root, ArrayList<Integer> arr) {
if (root == null) {
return arr;
}
inorder(root.left, arr);
arr.add(root.val);
inorder(root.right, arr);
return arr;
}
public int getK(TreeNode root, int k) {
ArrayList<Integer> arr = inorder(root, new ArrayList<>());
return arr.get(k - 1);
}
// 2、利用队列实现迭代,这样避免了检索所有的节点的情况
public int kthSmallest(TreeNode root, int k) {
LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
while (true) {
// 依次放入左节点
while (root != null) {
queue.add(root);
root = root.left;
}
// 取最后的节点,也就是当前列表中最小的节点,弹出
root = queue.removeLast();
// 第k小减减,判断是否符合k小的情况
if (--k == 0) return root.val;
// 如果节点有右节点,需要重新赋值右节点,依次放入,迭代
root = root.right;
}
}
}
PS:如果不对请指出,不喜勿喷。
力扣230题地址:https://leetcode-cn.com/problems/kth-smallest-element-in-a-bst/ ↩︎