一些思路不是很清晰的算法题

正则表达式匹配

public boolean isMatch(String s, String p) {
        if (s == null || p == null)
            return false;

        int m = s.length(), n = p.length();
        boolean[][] dp = new boolean[m + 1][n + 1];
        dp[0][0] = true;
        for (int j = 1; j <= n; j++) {
            if (p.charAt(j - 1) == '*') {
                dp[0][j] = dp[0][j - 2];
            }
        }

        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (s.charAt(i-1) == p.charAt(j-1) || p.charAt(j-1) == '.') {
                    dp[i][j] = dp[i-1][j-1];
                } else if (p.charAt(j-1) == '*') {
                    if (s.charAt(i-1) == p.charAt(j-2) || p.charAt(j-2) == '.') {
                        dp[i][j] = dp[i][j-2] || dp[i-1][j-2] || dp[i-1][j];    // 抵消0、1、多
                    } else {
                        dp[i][j] = dp[i][j-2];
                    }
                }
            }
        }
        return dp[m][n];
    }

字符串转数字

BST与双向链表

平衡二叉树

public boolean isBalanced(TreeNode root) {
        return depth(root) != -1;
    }

    public int depth(TreeNode root) {
        if (root == null)
            return 0;

        int leftDepth = depth(root.left);
        if (leftDepth == -1)
            return -1;

        int rightDepth = depth(root.right);
        if (rightDepth == -1)
            return -1;

        if (Math.abs(leftDepth - rightDepth) > 1)
            return -1;

        return 1 + Math.max(leftDepth, rightDepth);
    }

单向链表排序

   class ListNode {
        int val;
        ListNode next;
        ListNode(int x) { val = x; }
    }

    /** 单向链表快速排序 */
    public void quickSort(ListNode head) {
        if (head==null || head.next==null)
            return;
        quickSort(head, null);
    }

    private void quickSort(ListNode head, ListNode tail) {
        if (head == tail || head.next == tail)
            return;
        ListNode pivot = partition(head, tail);
        quickSort(head, pivot);
        quickSort(pivot.next, tail);
    }

    private ListNode partition(ListNode head, ListNode tail) {
        int pivot = head.val;
        ListNode left = head, right = head.next;
        while (right != tail) {
            if (right.val >= pivot) {
                right = right.next;
            } else {
                left.val = right.val;
                left = left.next;
                right.val = left.val;
                right = right.next;
            }
        }
        left.val = pivot;
        return left;
    }

数组中的逆序对

思路:借助归并排序的过程,进行统计。类似于判断平衡树,借助求深度的过程进行判断。

数组原地置换

给定一个数组a1,a2,a3,...an,b1,b2,b3..bn,最终把它置换成a1,b1,a2,b2,...an,bn。类似于完美洗牌问题。我觉得写出时间O(nlogn)、空间O(1)的就足够了。

    public int[] shuffle(int[] arr, int n) {
        int[] nums = Arrays.copyOf(arr, arr.length);
        shuffle(nums, n, 0, nums.length - 1);
        return nums;
    }

    private void shuffle(int[] nums, int len, int start, int end) {
        if (len == 1) return;

        // 处理len为奇数的情况,将前半部分的最后一个数换到倒第二的位置
        if ((len & 1) != 0) {
            int temp = nums[start + len - 1];
            for (int i = start + len; i < end; i++) {
                nums[i - 1] = nums[i];
            }
            nums[end - 1] = temp;

            len--;
            end -= 2;
        }

        // 将需要shuffle的部分数组等分为4部分,将第2、3部分整体置换
        int mid = start + ((end - start) >>> 1);
        int left = start + ((mid - start) >>> 1) + 1, right = mid + 1, temp;
        while (left <= mid) {
            temp = nums[left];
            nums[left++] = nums[right];
            nums[right++] = temp;
        }

        // 递归分治进行置换
        shuffle(nums, len >>> 1, start, mid);
        shuffle(nums, len >>> 1, mid + 1, end);
    }

猿辅导面试的两道算法题(LeetCode 93.复原IP地址、求有序数组里值<=target的最大序号)

这两道题乍看不是很难,但是细节比较重要。第一道题注意“127001”这种情况,第二道题注意可能造成死循环。```

      public List<String> restoreIpAddresses(String s) {
        List<String> res = new ArrayList<>();
        helper(s, res, new int[4], 0);
        return res;
    }

    private void helper(String s, List<String> res, int[] temp, int idx) {
        if (idx == 4) {
            if (s.length() == 0) {
                StringBuilder sb = new StringBuilder();
                sb.append(temp[0]);
                for (int i = 1; i < 4; i++) {
                    sb.append('.').append(temp[i]);
                }
                res.add(new String(sb));
            }
        } else {
            int num;
            for (int len = 1; len <= 3 && len <= s.length(); len++) {
                num = Integer.parseInt(s.substring(0, len));
                // 0、1、00、01、11、000、001、010、100、345 里面
                // 只有 0、1、11、100 合法,即 数值为0且长度为0、数值在1-255之间且第一位不为0 两种
                if ((num == 0 && len == 1) || (num > 0 && num < 256 && s.charAt(0) != '0')) {
                    temp[idx] = num;
                    helper(s.substring(len), res, temp, idx + 1);
                }
            }
        }
    }
      public static int rightBound(int[] nums, int target) {
        int lo = 0, hi = nums.length, mid;
        while (lo < hi) {
            mid = lo + ((hi - lo) >>> 1);
            if (nums[mid] <= target)
                lo = mid + 1;
            else
                hi = mid;
        }
        return lo - 1;
    }
posted @ 2020-08-02 16:47  y1x4  阅读(185)  评论(0)    收藏  举报