leetcode第 10 场双周赛 题解分享

1.三个有序数组的交集

给出三个均为 严格递增排列 的整数数组 arr1arr2arr3
返回一个由 仅 在这三个数组中 同时出现 的整数所构成的有序数组。

示例

输入: 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;
}
posted @ 2019-10-12 17:16  PowderSnow  阅读(222)  评论(0)    收藏  举报