leetcode第 10 场双周赛 题解分享
1.三个有序数组的交集
给出三个均为 严格递增排列 的整数数组 arr1,arr2 和 arr3。
返回一个由 仅 在这三个数组中 同时出现 的整数所构成的有序数组。
示例
输入: arr1 = [1,2,3,4,5], arr2 = [1,2,5,7,9], arr3 = [1,3,4,5,8]
输出: [1,5]
解释: 只有 1 和 5 同时在这三个数组中出现.
题解代码
public List<Integer> arraysIntersection(int[] arr1, int[] arr2, int[] arr3) {
List<Integer> res = new ArrayList<Integer>();
int i1 = 0, i2 = 0, i3 = 0;
while (i1 < arr1.length && i2 < arr2.length && i3 < arr3.length) {
if (arr1[i1] == arr2[i2] && arr1[i1] == arr3[i3]) {
res.add(arr1[i1]);
i1++; i2++; i3++;
}
else {
int ceiling = Math.max(arr1[i1], Math.max(arr2[i2], arr3[i3]));
while (i1 < arr1.length && arr1[i1] < ceiling) i1++;
while (i2 < arr2.length && arr2[i2] < ceiling) i2++;
while (i3 < arr3.length && arr3[i3] < ceiling) i3++;
}
}
return res;
}
2.查找两棵二叉搜索树之和
给出两棵二叉搜索树,请你从两棵树中各找出一个节点,使得这两个节点的值之和等于目标值 Target。
如果可以找到返回 True,否则返回 False。
示例1
输入: root1 = [2,1,4], root2 = [1,0,3], target = 5
输出: true
解释: 2 加 3 和为 5 。
示例2
输入: root1 = [0,-10,10], root2 = [5,1,7,0,2], target = 18
输出: false
题解代码
public boolean twoSumBSTs(TreeNode root1, TreeNode root2, int target) {
List<Integer> inorder = new ArrayList<Integer>();
inordertraversal(root1, inorder);
return traversal(root2, target, inorder);
}
private void inordertraversal(TreeNode root, List<Integer> inorder) {
if (root == null)
return;
inordertraversal(root.left, inorder);
inorder.add(root.val);
inordertraversal(root.right, inorder);
}
private boolean traversal(TreeNode root, int target, List<Integer> inorder) {
if (root == null)
return false;
return binary(target - root.val, inorder) || traversal(root.left, target, inorder) || traversal(root.right, target, inorder);
}
private boolean binary(int target, List<Integer> inorder) {
int lo = 0, hi = inorder.size() - 1;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
if (inorder.get(mid) == target)
return true;
if (inorder.get(mid) < target)
lo = mid + 1;
else
hi = mid - 1;
}
return false;
}
3.步进数
如果一个整数上的每一位数字与其相邻位上的数字的绝对差都是 1,那么这个数就是一个「步进数」。
例如,321 是一个步进数,而 421 不是。
给你两个整数,low 和 high,请你找出在 [low, high] 范围内的所有步进数,并返回 排序后 的结果。
示例:
输入: low = 0, high = 21
输出: [0,1,2,3,4,5,6,7,8,9,10,12,21]
题解代码:
public List<Integer> countSteppingNumbers(int low, int high) {
List<Integer> res = new ArrayList<Integer>();
if (low == 0) res.add(0);
int len1 = ((Integer) low).toString().length();
int len2 = ((Integer) high).toString().length();
for (int i = len1; i <= len2; i++)
for (int j = 1; j <= 9; j++)
dfs(res, j, 1, i, low, high);
return res;
}
private void dfs(List<Integer> res, int cur, int curlen, int len, int low, int high) {
if (curlen == len) {
if (cur >= low && cur <= high)
res.add(cur);
return;
}
if (cur > Integer.MAX_VALUE / 10)
return;
int lastnum = cur % 10;
if (lastnum >= 1)
dfs(res, cur * 10 + lastnum - 1, curlen + 1, len, low, high);
if (lastnum <= 8)
dfs(res, cur * 10 + lastnum + 1, curlen + 1, len, low, high);
}
4.验证回文字符串 III
给出一个字符串 s 和一个整数 k,请你帮忙判断这个字符串是不是一个「K 回文」。
所谓「K 回文」:如果可以通过从字符串中删去最多 k 个字符将其转换为回文,那么这个字符串就是一个 「K 回文」。
示例:
输入: s = "abcdeca", k = 2
输出: true
解释: 删除字符 “b” 和 “e”。
提示:
1 <= s.length <= 1000
s 中只含有小写英文字母
1 <= k <= s.length
题解代码:
public boolean isValidPalindrome(String s, int k) {
String rs = "";
for (int i = s.length() - 1; i >= 0; i--)
rs += s.charAt(i);
int[][] dp = new int[s.length()][s.length()];
dp[0][0] = s.charAt(0) == rs.charAt(0) ? 1 : 0;
for (int i = 1; i < s.length(); i++)
dp[i][0] = Math.max(dp[i - 1][0], s.charAt(i) == rs.charAt(0) ? 1 : 0);
for (int i = 1; i < rs.length(); i++)
dp[0][i] = Math.max(dp[0][i - 1], rs.charAt(i) == s.charAt(0) ? 1 : 0);
for (int i = 1; i < s.length(); i++) {
for (int j = 1; j < rs.length(); j++) {
if (s.charAt(i) == rs.charAt(j))
dp[i][j] = Math.max(dp[i - 1][j - 1] + 1, Math.max(dp[i - 1][j], dp[i][j - 1]));
else
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
return s.length() - dp[s.length() - 1][s.length() - 1] <= k;
}

浙公网安备 33010602011771号