《剑指offer》专题

1 基础知识

面试题3:数组中重复的数字

https://leetcode.cn/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/

class Solution {
    public int findRepeatNumber(int[] nums) {
        Arrays.sort(nums);
        for (int i = 0; i < nums.length - 1; i++) {
            if (nums[i] == nums[i + 1]) {
                return nums[i];
            }
        }
        return Integer.MAX_VALUE;
    }
}

面试题4:二维数组中的查找

https://leetcode.cn/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/

class Solution {
    public boolean findNumberIn2DArray(int[][] matrix, int target) {
        if (matrix.length < 1 || matrix[0].length < 1) {
            return false;
        }
        int i = 0;
        int j = matrix[i].length - 1;
        while (i < matrix.length && j >= 0) {
            if (matrix[i][j] == target) {
                return true;
            } else if (matrix[i][j] > target) {
                j--;
            } else {
                i++;
            }
        }
        return false;
    }
}

面试官5:替换空格

https://leetcode.cn/problems/ti-huan-kong-ge-lcof/

class Solution {
    public String replaceSpace(String s) {
        char[] cArray = s.toCharArray();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < cArray.length; i++) {
            sb.append(Character.isSpaceChar(cArray[i]) ? "%20" : cArray[i]);
        }
        return sb.toString();
    }
}

面试题6:从尾到头打印链表

https://leetcode.cn/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/

class Solution {
    List<Integer> list = new ArrayList<>();

    public int[] reversePrint(ListNode head) {
        if (head == null) {
            return new int[0];
        }
        reverse(head);
        int[] array = new int[list.size()];
        for (int i = 0; i < array.length; i++) {
            array[i] = list.get(i);
        }
        return array;
    }

    public void reverse(ListNode head) {
        if (head.next != null) {
            reversePrint(head.next);
        }
        list.add(head.val);
    }
}

面试题9:用两个栈实现队列

https://leetcode.cn/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/

class CQueue {
    Stack<Integer> stack1;
    Stack<Integer> stack2;

    public CQueue() {
        stack1 = new Stack();
        stack2 = new Stack();
    }

    public void appendTail(int value) {
        stack2.push(value);
    }

    public int deleteHead() {
        int head = -1;
        if (stack1.size() > 0 || stack2.size() > 0) {
            if (stack1.size() == 0 && stack2.size() > 0) {
                while (stack2.size() > 0) {
                    stack1.push(stack2.pop());
                }
            }
            head = stack1.pop();
        }
        return head;
    }
}

面试题10-1:斐波那契数列

https://leetcode.cn/problems/fei-bo-na-qi-shu-lie-lcof/

class Solution {
   public int fib(int n) {
        int x = 0;
        int y = 1;
        int z = 1;
        while (n > 0) {
            z = (x + y) % 1000000007;
            x = y;
            y = z;
            n--;
        }
        return x;
    }
}

面试题10-2:青蛙跳台阶问题

https://leetcode.cn/problems/qing-wa-tiao-tai-jie-wen-ti-lcof/

class Solution {
    Map<Integer, Integer> map = new HashMap();

    public int numWays(int n) {
        if (n == 1) {
            return 1;
        }
        if (n == 2) {
            return 2;
        }
        if (n > 2) {
            if (map.containsKey(n)) {
                return map.get(n);
            }
            int num = (numWays(n - 1) + numWays(n - 2)) % 1000000007;
            map.put(n, num);
            return num;
        }
        return 1;
    }
}

面试题11:旋转数组的最小数字

https://leetcode.cn/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/

class Solution {
    public int minArray(int[] numbers) {
        if (numbers.length == 0) {
            return Integer.MAX_VALUE;
        }
        int result = numbers[0];
        for (int i = 0; i < numbers.length - 1; i++) {
            if (numbers[i] > numbers[i + 1]) {
                return numbers[i + 1];
            }
        }
        return result;
    }
}

面试题12:矩阵中的路径

https://leetcode.cn/problems/ju-zhen-zhong-de-lu-jing-lcof/

class Solution {
    public boolean exist(char[][] board, String word) {
        if ("".equals(word)) {
            return true;
        }
        if (board.length == 0 || board[0].length == 0) {
            return false;
        }
        boolean[][] passed = new boolean[board.length][board[0].length];
        char[] cArray = word.toCharArray();
        List<String> starts = new ArrayList();
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                if (board[i][j] == cArray[0]) {
                    starts.add(i + "," + j);
                }
            }
        }
        if (!starts.isEmpty()) {
            for (int k = 0; k < starts.size(); k++) {
                String[] strs = starts.get(k).split(",");
                int x = Integer.parseInt(strs[0]);
                int y = Integer.parseInt(strs[1]);
                passed[x][y] = true;
                if (next(board, cArray, x, y, 1, passed)) {
                    return true;
                }
                passed[x][y] = false;
            }
        }
        return false;
    }

    public boolean next(char[][] board, char[] cArray, int x, int y, int next, boolean[][] passed) {
        if (next == cArray.length) {
            return true;
        }
        boolean bool;
        if (x > 0 && board[x - 1][y] == cArray[next] && !passed[x - 1][y]) {
            passed[x - 1][y] = true;
            bool = next(board, cArray, x - 1, y, next + 1, passed);
            passed[x - 1][y] = false;
            if (bool) {
                return true;
            }
        }
        if (y > 0 && board[x][y - 1] == cArray[next] && !passed[x][y - 1]) {
            passed[x][y - 1] = true;
            bool = next(board, cArray, x, y - 1, next + 1, passed);
            passed[x][y - 1] = false;
            if (bool) {
                return true;
            }
        }
        if (x < board.length - 1 && board[x + 1][y] == cArray[next] && !passed[x + 1][y]) {
            passed[x + 1][y] = true;
            bool = next(board, cArray, x + 1, y, next + 1, passed);
            passed[x + 1][y] = false;
            if (bool) {
                return true;
            }
        }
        if (y < board[0].length - 1 && board[x][y + 1] == cArray[next] && !passed[x][y + 1]) {
            passed[x][y + 1] = true;
            bool = next(board, cArray, x, y + 1, next + 1, passed);
            passed[x][y + 1] = false;
            if (bool) {
                return true;
            }
        }
        return false;
    }
}

面试题13:机器人的运动范围

https://leetcode.cn/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/

class Solution {
    int count;

    public int movingCount(int m, int n, int k) {
        count = 0;
        boolean[][] booleans = new boolean[m][n];
        analyze(m, n, 0, 0, k, booleans);
        return count;
    }

    public void analyze(int m, int n, int i, int j, int k, boolean[][] booleans) {
        if (getCompareResult(i) + getCompareResult(j) <= k && !booleans[i][j]) {
            booleans[i][j] = true;
            count++;
        }
        if (i > 0 && getCompareResult(i - 1) + getCompareResult(j) <= k && !booleans[i - 1][j]) {
            analyze(m, n, i - 1, j, k, booleans);
        }
        if (j > 0 && getCompareResult(i) + getCompareResult(j - 1) <= k && !booleans[i][j - 1]) {
            analyze(m, n, i, j - 1, k, booleans);
        }
        if (i < m - 1 && getCompareResult(i + 1) + getCompareResult(j) <= k
            && !booleans[i + 1][j]) {
            analyze(m, n, i + 1, j, k, booleans);
        }
        if (j < n - 1 && getCompareResult(i) + getCompareResult(j + 1) <= k
            && !booleans[i][j + 1]) {
            analyze(m, n, i, j + 1, k, booleans);
        }
    }

    public int getCompareResult(int num) {
        int sum = 0;
        while (num != 0) {
            sum = sum + num % 10;
            num = num / 10;
        }
        return sum;
    }
}

面试题14-1:剪绳子

https://leetcode.cn/problems/jian-sheng-zi-lcof/

class Solution {
    public int cuttingRope(int n) {
        // 由题意,m>=2
        int max = Integer.MIN_VALUE;
        int mMax;
        int base;
        int rest;
        for (int m = 2; m <= n; m++) {
            base = n / m;
            rest = n % m;
            // m个数,rest个base+1,m-rest个base
            mMax = (int) (Math.pow(base, m - rest) * Math.pow(base + 1, rest));
            if (mMax > max) {
                max = mMax;
            }
        }
        return max;
    }
}

面试题15:二进制中1的个数

https://leetcode.cn/problems/er-jin-zhi-zhong-1de-ge-shu-lcof/

class Solution {
    public int hammingWeight(int n) {
        int count = 0;
        for (int i = 0; i < 32; i++) {
            if ((n & (1 << i)) != 0) {
                count++;
            }
        }
        return count;
    }
}

2 代码质量

面试题16:数值的整数次方

https://leetcode.cn/problems/shu-zhi-de-zheng-shu-ci-fang-lcof/

class Solution {
    Map<Long, Double> map = new HashMap<>();

    public double myPow(double x, int n) {
        if (x == 0 && n < 0) {
            return 0;
        }
        long lnl;
        if (n != Integer.MIN_VALUE) {
            lnl = n > 0 ? n : -n;
        } else {
            lnl = 2147483648L;
        }
        double result = getResult(x, lnl);
        if (n > 0) {
            return result;
        } else {
            return 1.0 / result;
        }
    }

    public double getResult(double x, long n) {
        if (n == 0) {
            return 1;
        }
        if (n == 1) {
            return x;
        }
        if (map.containsKey(n)) {
            return map.get(n);
        }
        if (n % 2 == 0) {
            map.put(n, getResult(x, n / 2) * getResult(x, n / 2));

        } else {
            map.put(n, getResult(x, n / 2) * getResult(x, n / 2) * x);
        }
        return map.get(n);
    }
}

面试题17:打印从1到最大的n位数

https://leetcode.cn/problems/da-yin-cong-1dao-zui-da-de-nwei-shu-lcof/

class Solution {
    public int[] printNumbers(int n) {
        int count = (int) (Math.pow(10, n) - 1);
        int[] result = new int[count];
        for (int i = 0; i < count; i++) {
            result[i] = i + 1;
        }
        return result;
    }
}

面试题18:删除链表的节点

https://leetcode.cn/problems/shan-chu-lian-biao-de-jie-dian-lcof/

class Solution {
    public ListNode deleteNode(ListNode head, int val) {
        if (head == null) {
            return null;
        }
        if (head.next == null) {
            if (head.val == val) {
                return null;
            } else {
                return head;
            }
        }
        ListNode p1 = new ListNode(0);
        p1.next = head;
        ListNode p2 = head.next != null ? head.next : null;
        ListNode p3 = p1;
        while (p2 != null) {
            if (head.val == val) {
                p1.next = p2;
                break;
            }
            p2 = p2.next != null ? p2.next : null;
            head = head.next;
            p1 = p1.next;
        }
        if (head.val == val) {
            p1.next = p2;
        }
        return p3.next != null ? p3.next : null;
    }
}

面试题20:表示数值的字符串

https://leetcode.cn/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof/

class Solution {
    static List<Character> list;
    static {
        list = new ArrayList();
        list.add('0');
        list.add('1');
        list.add('2');
        list.add('3');
        list.add('4');
        list.add('5');
        list.add('6');
        list.add('7');
        list.add('8');
        list.add('9');
    }

    public boolean isNumber(String s) {
        String trimS = s.trim();
        String upTrimS = trimS.toUpperCase();
        if ("".equals(upTrimS)) {
            return false;
        }
        char[] charS = upTrimS.toCharArray();

        boolean containsE = false;
        for (int i = 0; i < charS.length; i++) {
            if (charS[i] == 'e' || charS[i] == 'E') {
                containsE = true;
                break;
            }
        }
        if (containsE) {
            if (charS[0] == 'E' || charS[charS.length - 1] == 'E') {
                return false;
            }
            String[] byE = upTrimS.split("E");
            if (byE.length != 2) {
                return false;
            }
            char[] spilt1 = byE[0].toCharArray();
            char[] spilt2 = byE[1].toCharArray();
            if (spilt1.length == 0) {
                return false;
            }
            if (!isIntNumber(spilt2)) {
                return false;
            }
            charS = spilt1;
        }

        int countPoint = 0;
        boolean containsNum = false;
        for (int k = 0; k < charS.length; k++) {
            if (k == 0 && (charS[k] == '+' || charS[k] == '-')) {
                continue;
            }
            if (charS[k] == '.') {
                countPoint++;
                continue;
            }
            if (!list.contains(charS[k])) {
                return false;
            } else {
                containsNum = true;
            }
        }
        if (!containsNum || countPoint > 1) {
            return false;
        }

        return true;
    }

    public boolean isIntNumber(char[] array) {
        for (int j = 0; j < array.length; j++) {
            if (j == 0 && (array[j] == '+' || array[j] == '-')) {
                if (array.length == 1) {
                    return false;
                }
                continue;
            }
            if (!list.contains(array[j])) {
                return false;
            }
        }
        return true;
    }
}

面试题21:调整数组顺序使奇数位于偶数前面

https://leetcode.cn/problems/diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof/

class Solution {
    int mark;

    public int[] exchange(int[] nums) {
        if (nums.length < 2) {
            return nums;
        }
        int p1 = 0;
        int p2 = nums.length - 1;
        while (p1 < p2) {
            if (nums[p1] % 2 == 1) {
                p1++;
                continue;
            }
            if (nums[p2] % 2 == 0) {
                p2--;
                continue;
            }
            mark = nums[p1];
            nums[p1] = nums[p2];
            nums[p2] = mark;
            p1++;
            p2--;
        }
        return nums;
    }
}

面试题22:链表中倒数第k个节点

https://leetcode.cn/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/

class Solution {
    int      count = Integer.MIN_VALUE;
    ListNode Kth;

    public ListNode getKthFromEnd(ListNode head, int k) {
        if (head == null) {
            return null;
        }
        getKth(head, k);
        return Kth;
    }

    public void getKth(ListNode head, int k) {
        if (head.next == null) {
            count = 1;
        } else {
            getKth(head.next, k);
            count++;
        }
        if (count == k) {
            Kth = head;
        }
    }
}

面试题24:反转链表

https://leetcode.cn/problems/fan-zhuan-lian-biao-lcof/

class Solution {
    ListNode p1;
    ListNode p2;

    public ListNode reverseList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        while (head.next != null) {
            p2 = head.next;
            head.next = p1;
            p1 = head;
            head = p2;
        }
        head.next = p1;
        return head;
    }
}

面试题25:合并两个排序的链表

https://leetcode.cn/problems/he-bing-liang-ge-pai-xu-de-lian-biao-lcof/

class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if (l1 == null) {
            return l2;
        }
        if (l2 == null) {
            return l1;
        }
        ListNode stone = new ListNode(0);
        ListNode current = stone;
        while (l1 != null || l2 != null) {
            if (l1.val <= l2.val) {
                current.next = l1;
                l1 = l1.next != null ? l1.next : new ListNode(Integer.MAX_VALUE);
            } else {
                current.next = l2;
                l2 = l2.next != null ? l2.next : new ListNode(Integer.MAX_VALUE);
            }
            current = current.next;
            if (l1.val == Integer.MAX_VALUE && l2.val == Integer.MAX_VALUE) {
                break;
            }
        }
        return stone.next;
    }
}

面试题26:树的子结构

https://leetcode.cn/problems/shu-de-zi-jie-gou-lcof/

class Solution {
    boolean is = false;

    public boolean isSubStructure(TreeNode A, TreeNode B) {
        if (B == null) {
            return is;
        }
        dfs(A, B, B.val);
        return is;
    }

    public void dfs(TreeNode node1, TreeNode node2, int root) {
        if (node1 == null) {
            return;
        }
        if (!is){
            if (node1.val == root) {
                is = compare(node1, node2);
            }
            dfs(node1.left, node2, root);
            dfs(node1.right, node2, root);
        }
    }

    public boolean compare(TreeNode node1, TreeNode node2) {
        if (node1 == null) {
            return false;
        }
        if (node1.val != node2.val) {
            return false;
        }
        boolean b1 = true;
        boolean b2 = true;
        if (node2.left != null) {
            b1 = compare(node1.left, node2.left);
        }
        if (node2.right != null) {
            b2 = compare(node1.right, node2.right);
        }
        return b1 && b2;
    }
}

3 解题思路

面试题27:二叉树的镜像

https://leetcode.cn/problems/er-cha-shu-de-jing-xiang-lcof/

class Solution {
    TreeNode treeNode;

    public TreeNode mirrorTree(TreeNode root) {
        if (root == null) {
            return null;
        }
        mirror(root);
        return root;
    }

    public void mirror(TreeNode node) {
        treeNode = node.left;
        node.left = node.right;
        node.right = treeNode;
        if (node.left != null) {
            mirror(node.left);
        }
        if (node.right != null) {
            mirror(node.right);
        }
    }
}

面试题28:对称的二叉树

https://leetcode.cn/problems/dui-cheng-de-er-cha-shu-lcof/

class Solution {
    public boolean isSymmetric(TreeNode root) {
        if (root == null) {
            return true;
        }
        return compare(root.left, root.right);
    }

    public boolean compare(TreeNode node1, TreeNode node2) {
        if (node1 == null && node2 == null) {
            return true;
        }
        if (node1 == null || node2 == null) {
            return false;
        }
        if (node1.val != node2.val) {
            return false;
        }
        return compare(node1.left, node2.right) && compare(node1.right, node2.left);
    }
}

面试题29:顺时针打印矩阵

https://leetcode.cn/problems/shun-shi-zhen-da-yin-ju-zhen-lcof/

class Solution {
    int           mark = 0;                // 0:向右 1:向下 2:向左 3:向上
    List<Integer> list = new ArrayList<>();

    public int[] spiralOrder(int[][] matrix) {
        if (matrix.length == 0 || matrix[0].length == 0) {
            return new int[0];
        }
        work(matrix, 0, 0, 0, matrix[0].length - 1, 0, matrix.length - 1);
        int[] result = new int[list.size()];
        for (int k = 0; k < result.length; k++) {
            result[k] = list.get(k);
        }
        return result;
    }

    public void work(int[][] matrix, int i, int j, int left, int right, int top, int bottom) {
        if (left > right || top > bottom) {
            return;
        }
        list.add(matrix[i][j]);
        if (mark == 0) {
            if (j < right) {
                work(matrix, i, j + 1, left, right, top, bottom);
            } else {
                top++;
                mark = 1;
                work(matrix, i + 1, j, left, right, top, bottom);
            }
            return;
        }
        if (mark == 1) {
            if (i < bottom) {
                work(matrix, i + 1, j, left, right, top, bottom);
            } else {
                right--;
                mark = 2;
                work(matrix, i, j - 1, left, right, top, bottom);
            }
            return;
        }
        if (mark == 2) {
            if (j > left) {
                work(matrix, i, j - 1, left, right, top, bottom);
            } else {
                bottom--;
                mark = 3;
                work(matrix, i - 1, j, left, right, top, bottom);
            }
            return;
        }
        if (mark == 3) {
            if (i > top) {
                work(matrix, i - 1, j, left, right, top, bottom);
            } else {
                left++;
                mark = 0;
                work(matrix, i, j + 1, left, right, top, bottom);
            }
            return;
        }
    }
}

面试题30:包含min函数的栈

https://leetcode.cn/problems/bao-han-minhan-shu-de-zhan-lcof/

class MinStack {
    Stack<Integer> stack1;
    Stack<Integer> stack2;
    int            min;

    public MinStack() {
        stack1 = new Stack();
        stack2 = new Stack();
        min = Integer.MAX_VALUE;
    }

    public void push(int x) {
        stack1.push(x);
        if (x < min) {
            min = x;
        }
        stack2.push(min);
    }

    public void pop() {
        stack1.pop();
        stack2.pop();
        if (!stack2.empty()) {
            min = stack2.peek();
        } else {
            min = Integer.MAX_VALUE;
        }
    }

    public int top() {
        return stack1.peek();
    }

    public int min() {
        return stack2.peek();
    }
}

面试题31:栈的压入、弹出序列

https://leetcode.cn/problems/zhan-de-ya-ru-dan-chu-xu-lie-lcof/

class Solution {
    public boolean validateStackSequences(int[] pushed, int[] popped) {
        if (pushed.length != popped.length) {
            return false;
        }
        if (pushed.length == 0) {
            return true;
        }
        // 一个数据出栈时,必须是栈顶元素或未进栈元素
        Stack<Integer> stack = new Stack<>();
        int count = 0;

        for (int i = 0; i < popped.length; i++) {
            if (stack.contains(popped[i])) {
                if (stack.peek() != popped[i]) {
                    return false;
                }
                stack.pop();
                continue;
            }
            for (int j = count; j < pushed.length; j++) {
                stack.add(pushed[j]);
                count++;
                if (pushed[j] == popped[i]) {
                    stack.pop();
                    break;
                }
            }
        }

        if (stack.size() == 0) {
            return true;
        } else {
            return false;
        }
    }
}

面试题32-1:从上到下打印二叉树

https://leetcode.cn/problems/cong-shang-dao-xia-da-yin-er-cha-shu-lcof/

class Solution {
    List<Integer>   list  = new ArrayList<>();
    Queue<TreeNode> queue = new LinkedList<>();

    public int[] levelOrder(TreeNode root) {
        if (root == null) {
            return new int[0];
        }
        addNode(root);
        while (!queue.isEmpty()) {
            addNode(queue.poll());
        }
        int[] array = new int[list.size()];
        for (int i = 0; i < list.size(); i++) {
            array[i] = list.get(i);
        }
        return array;
    }

    public void addNode(TreeNode node) {
        list.add(node.val);
        if (node.left != null) {
            queue.add(node.left);
        }
        if (node.right != null) {
            queue.add(node.right);
        }
    }
}

面试题32-2:从上到下打印二叉树2

https://leetcode.cn/problems/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof/

class Solution {
    List<List<Integer>>         lists        = new ArrayList<>(); //result
    Map<Integer, List<Integer>> levelListMap = new HashMap<>();   //key:level, value:list
    Map<TreeNode, Integer>      nodeLevelMap = new HashMap<>();   //key:node, value:level
    Queue<TreeNode>             queue        = new LinkedList<>();

    public List<List<Integer>> levelOrder(TreeNode root) {
        if (root == null) {
            return new ArrayList<>();
        }
        nodeLevelMap.put(root, 1);
        addNode(root);
        while (!queue.isEmpty()) {
            addNode(queue.poll());
        }
        for (int i = 1; true; i++) {
            if (levelListMap.containsKey(i)) {
                lists.add(levelListMap.get(i));
            } else {
                break;
            }
        }
        return lists;
    }

    public void addNode(TreeNode node) {
        if (!levelListMap.containsKey(nodeLevelMap.get(node))) {
            levelListMap.put(nodeLevelMap.get(node), new ArrayList<>());
        }
        levelListMap.get(nodeLevelMap.get(node)).add(node.val);

        if (node.left != null) {
            queue.add(node.left);
            nodeLevelMap.put(node.left, nodeLevelMap.get(node) + 1);
        }
        if (node.right != null) {
            queue.add(node.right);
            nodeLevelMap.put(node.right, nodeLevelMap.get(node) + 1);
        }
    }
}

面试题32-3:从上到下打印二叉树3

https://leetcode.cn/problems/cong-shang-dao-xia-da-yin-er-cha-shu-iii-lcof/

class Solution {
    List<List<Integer>>         lists        = new ArrayList<>();
    Map<Integer, List<Integer>> levelListMap = new HashMap<>();   //key:level, value:list
    Map<TreeNode, Integer>      nodeLevelMap = new HashMap<>();   //key:node, value:level
    Queue<TreeNode>             queue        = new LinkedList<>();

    public List<List<Integer>> levelOrder(TreeNode root) {
        if (root == null) {
            return new ArrayList<>();
        }
        nodeLevelMap.put(root, 1);
        addNode(root);
        while (!queue.isEmpty()) {
            addNode(queue.poll());
        }
        for (int i = 1; true; i++) {
            if (levelListMap.containsKey(i)) {
                lists.add(levelListMap.get(i));
            } else {
                break;
            }
        }
        return lists;
    }

    public void addNode(TreeNode node) {
        if (!levelListMap.containsKey(nodeLevelMap.get(node))) {
            levelListMap.put(nodeLevelMap.get(node), new ArrayList<>());
        }
        if (nodeLevelMap.get(node) % 2 == 1) {
            levelListMap.get(nodeLevelMap.get(node)).add(node.val);
        } else {
            levelListMap.get(nodeLevelMap.get(node)).add(0, node.val); //头插入
        }

        if (node.left != null) {
            queue.add(node.left);
            nodeLevelMap.put(node.left, nodeLevelMap.get(node) + 1);
        }
        if (node.right != null) {
            queue.add(node.right);
            nodeLevelMap.put(node.right, nodeLevelMap.get(node) + 1);
        }
    }
}

面试题33:二叉搜索树的后序遍历序列

https://leetcode.cn/problems/er-cha-sou-suo-shu-de-hou-xu-bian-li-xu-lie-lcof/

class Solution {
    boolean is = true;

    public boolean verifyPostorder(int[] postorder) {
        if (postorder.length == 0) {
            return true;
        }
        work(postorder, postorder.length - 1);
        return is;
    }

    public void work(int[] postorder, int right) {
        if (postorder[0] > postorder[right]) {
            for (int i = 0; i < right; i++) {
                if (postorder[i] < postorder[right]) {
                    is = false;
                }
            }
        } else {
            boolean change = false;
            for (int i = 0; i < right; i++) {
                if (postorder[i] > postorder[right]) {
                    change = true;
                }
                if (change && postorder[i] < postorder[right]) {
                    is = false;
                }
            }
        }
        if (right > 0) {
            work(postorder, right - 1);
        }
    }
}

面试题34:二叉树中和为某一值的路径

https://leetcode.cn/problems/er-cha-shu-zhong-he-wei-mou-yi-zhi-de-lu-jing-lcof/

class Solution {
    List<List<Integer>> lists  = new ArrayList<>();
    Stack<TreeNode>     stack1 = new Stack<>();
    Stack<TreeNode>     stack2 = new Stack<>();

    public List<List<Integer>> pathSum(TreeNode root, int target) {
        if (root == null) {
            return new ArrayList<>();
        }
        int currentSum = root.val;
        work(root, currentSum, target);
        return lists;
    }

    public void work(TreeNode node, int currentSum, int target) {
        stack1.push(node);
        if (node.left == null && node.right == null && target - currentSum == 0) {
            while (!stack1.isEmpty()) {
                stack2.push(stack1.pop());
            }
            TreeNode tn;
            List<Integer> list = new ArrayList<>();
            while (!stack2.isEmpty()) {
                tn = stack2.pop();
                list.add(tn.val);
                stack1.push(tn);
            }
            lists.add(list);
        }
        if (node.left != null) {
            work(node.left, currentSum + node.left.val, target);
        }
        if (node.right != null) {
            work(node.right, currentSum + node.right.val, target);
        }
        stack1.pop();
    }
}

面试题35:复杂链表的复制

https://leetcode.cn/problems/fu-za-lian-biao-de-fu-zhi-lcof/

class Solution {
    Map<Node, Node> map = new HashMap<>();
    Node            p1;
    Node            p2;

    public Node copyRandomList(Node head) {
        if (head == null) {
            return null;
        }
        p1 = head;
        Node head2 = new Node(0);
        p2 = head2;
        while (p1 != null) {
            p2.next = new Node(p1.val);
            p2 = p2.next;
            p2.random = p1.random;
            map.put(p1, p2);
            if (p1.next != null) {
                p1 = p1.next;
            } else {
                p1 = null;
            }
        }

        p2 = head2.next;
        while (p2 != null) {
            p2.random = map.get(p2.random);
            if (p2.next != null) {
                p2 = p2.next;
            } else {
                p2 = null;
            }
        }

        return head2.next;
    }
}

面试题36:二叉搜索树与双向链表

https://leetcode.cn/problems/er-cha-sou-suo-shu-yu-shuang-xiang-lian-biao-lcof/

class Solution {
    Node pre = null;
    Node head;

    public Node treeToDoublyList(Node root) {
        if (root == null) {
            return null;
        }
        dfs(root);
        head.left = pre;
        pre.right = head;
        return head;
    }

    public void dfs(Node node) {
        if (node == null) {
            return;
        }
        dfs(node.left);
        if (head == null) {
            head = node;
        }
        if (pre != null) {
            pre.right = node;
            node.left = pre;
        }
        pre = node; // 4
        dfs(node.right);
    }
}

面试题38:字符串的排列

https://leetcode.cn/problems/zi-fu-chuan-de-pai-lie-lcof/

class Solution {
    public String[] permutation(String s) {
        if (s.length() == 0) {
            return new String[] { "" };
        }
        char[] chars = s.toCharArray();
        Arrays.sort(chars);

        Queue<String> queue = new LinkedList<>();
        String current;
        int currentLength = 0;
        for (int i = 0; i < chars.length; i++) {
            currentLength++;
            if (queue.isEmpty()) {
                queue.add(String.valueOf(chars[i]));
                continue;
            }
            while (!queue.isEmpty()) {
                if (queue.peek().length() == currentLength) {
                    break;
                }
                current = ((LinkedList<String>) queue).pop();
                for (int k = 0; k <= current.length(); k++) {
                    StringBuilder sb = new StringBuilder();
                    sb.append(current);
                    sb.insert(k, chars[i]);
                    queue.add(sb.toString());
                }
            }
        }

        Set<String> set = new HashSet<>();
        set.addAll(queue);
        String[] strs = set.stream().toArray(String[]::new);

        return strs;
    }
}

4 优化时间和空间效率

面试题39:数组中出现次数超过一半的数字

https://leetcode.cn/problems/shu-zu-zhong-chu-xian-ci-shu-chao-guo-yi-ban-de-shu-zi-lcof/

class Solution {
    public int majorityElement(int[] nums) {
        if (nums.length == 1 || nums.length == 2) {
            return nums[0];
        }
        Arrays.sort(nums);
        return nums[nums.length / 2];
    }
}

面试题40:最小的k个数

https://leetcode.cn/problems/zui-xiao-de-kge-shu-lcof/

class Solution {
    public int[] getLeastNumbers(int[] arr, int k) {
        Arrays.sort(arr);
        int[] result = new int[k];
        for (int i = 0; i < k; i++) {
            result[i] = arr[i];
        }
        return result;
    }
}

面试题41:数据流中的中位数

https://leetcode.cn/problems/shu-ju-liu-zhong-de-zhong-wei-shu-lcof/

class MedianFinder {
    List<Integer> list;
    double        median;

    public MedianFinder() {
        list = new ArrayList<>();
    }

    public void addNum(int num) {
        if (list.size() == 0 || list.get(list.size() - 1) <= num) {
            list.add(num);
        } else {
            for (int i = 0; i < list.size(); i++) {
                if (list.get(i) > num) {
                    list.add(i, num);
                    break;
                }
            }
        }
    }

    public double findMedian() {
        if (list.size() % 2 == 1) {
            median = (double) list.get(list.size() / 2);
        } else {
            median = (double) (list.get(list.size() / 2 - 1) + list.get(list.size() / 2)) / 2;
        }
        return median;
    }
}

面试题42:连续子数组的最大和

https://leetcode.cn/problems/lian-xu-zi-shu-zu-de-zui-da-he-lcof/

class Solution {
    public int maxSubArray(int[] nums) {
        int sum = 0;
        int maxSum = Integer.MIN_VALUE;
        int maxNum = Integer.MIN_VALUE;
        for (int i = 0; i < nums.length; i++) {
            sum = sum + nums[i];
            if (nums[i] > 0 && sum > maxSum) {
                maxSum = sum;
            }
            if (sum < 0) {
                sum = 0;
            }
            if (nums[i] > maxNum) {
                maxNum = nums[i];
            }
        }
        if (maxSum < 0) {
            maxSum = maxNum;
        }
        return maxSum;
    }
}

面试题44:数字序列中某一位数字

https://leetcode.cn/problems/shu-zi-xu-lie-zhong-mou-yi-wei-de-shu-zi-lcof/

class Solution {
    public int findNthDigit(int n) {
        if (n < 10) {
            return n;
        }
        long sum = 0L;
        long lastSum = 0L;
        int k = 0;
        while (sum < n) {
            lastSum = sum;
            sum = (long) (sum + 9 * Math.pow(10, k) * (k + 1));
            k++;
        }

        long rest = n - lastSum;
        long begin = (long) Math.pow(10, k - 1);
        long result = begin + (rest - 1) / k;

        char[] chars = String.valueOf(result).toCharArray();
        int index = (int) ((rest - 1) % k);

        return (int) Long.parseLong(String.valueOf(chars[index]));
    }
}

面试题46:把数字翻译成字符串

https://leetcode.cn/problems/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof/

class Solution {
    Map<Integer, Integer> map = new HashMap();

    public int translateNum(int num) {
        if (num == 0) {
            return 1;
        }
        List<Integer> list = new LinkedList<>();
        while (num != 0) {
            list.add(0, num % 10);
            num = num / 10;
        }
        return getNum(list, list.size() - 1);
    }

    public int getNum(List<Integer> list, int index) {
        if (map.containsKey(index)) {
            return map.get(index);
        }
        if (index == 0) {
            return 1;
        }
        if (index == 1) {
            if ((list.get(index - 1) == 1) || (list.get(index - 1) == 2 && list.get(index) <= 5)) {
                return 2;
            }
            return 1;
        }
        if ((list.get(index - 1) == 1) || (list.get(index - 1) == 2 && list.get(index) <= 5)) {
            map.put(index, getNum(list, index - 1) + getNum(list, index - 2));
        } else {
            map.put(index, getNum(list, index - 1));
        }
        return map.get(index);
    }
}

面试题47:礼物的最大价值

https://leetcode.cn/problems/li-wu-de-zui-da-jie-zhi-lcof/

class Solution {
    Map<String, Integer> map = new HashMap<>();

    public int maxValue(int[][] grid) {
        if (grid.length < 1 || grid[0].length < 1) {
            return 0;
        }
        int m = grid.length;
        int n = grid[0].length;
        int result = getValue(grid, m - 1, n - 1);
        return result;
    }

    public int getValue(int[][] grid, int x, int y) {
        if (x < 0 || y < 0) {
            return 0;
        }
        if (map.containsKey(x + "," + y)) {
            return map.get(x + "," + y);
        } else {
            map.put(x + "," + y,
                grid[x][y] + compare(getValue(grid, x - 1, y), getValue(grid, x, y - 1)));
            return map.get(x + "," + y);
        }
    }

    public int compare(int a, int b) {
        return a >= b ? a : b;
    }
}

面试题48:最长不含重复字符的子字符串

https://leetcode.cn/problems/zui-chang-bu-han-zhong-fu-zi-fu-de-zi-zi-fu-chuan-lcof/

class Solution {
    Set<Character> set = new HashSet<>();

    public int lengthOfLongestSubstring(String s) {
        if ("".equals(s)) {
            return 0;
        }
        char[] arr = s.toCharArray();
        int maxSize = 0;
        int begin = 0;
        int current = 0;
        while (current < arr.length) {
            if (!set.contains(arr[current])) {
                set.add(arr[current]);
                if (maxSize < current - begin + 1) {
                    maxSize = current - begin + 1;
                }
            } else {
                while (arr[begin] != arr[current]) {
                    set.remove(arr[begin]);
                    begin++;
                }
                begin++;
            }
            current++;
        }
        return maxSize;
    }
}

面试题49:丑数

https://leetcode.cn/problems/chou-shu-lcof/

class Solution {
    public int nthUglyNumber(int n) {
        int p2 = 0;
        int p3 = 0;
        int p5 = 0;
        int[] dp = new int[n];
        dp[0] = 1;
        for(int i = 1; i < n; i++){
            dp[i] = Math.min(dp[p2] * 2, Math.min(dp[p3] * 3, dp[p5] * 5));
            if(dp[i] == dp[p2] * 2){
                p2++;
            }
            if(dp[i] == dp[p3] * 3){
                p3++;
            }
            if(dp[i] == dp[p5] * 5){
                p5++;
            }
        }
        return dp[n - 1];
    }
}

面试题50:第一个只出现一次的字符

https://leetcode.cn/problems/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof/

class Solution {
    public char firstUniqChar(String s) {
        if ("".equals(s)) {
            return ' ';
        }
        char[] cArray = s.toCharArray();
        Map<Character, Integer> map = new HashMap<>();
        int count;
        for (int i = 0; i < cArray.length; i++) {
            count = 1;
            if (map.containsKey(cArray[i])) {
                count = map.get(cArray[i]) + 1;
            }
            map.put(cArray[i], count);
        }
        for (int j = 0; j < cArray.length; j++) {
            if (map.get(cArray[j]) == 1) {
                return cArray[j];
            }
        }
        return ' ';
    }
}

面试题52:两个链表的第一个公共节点

https://leetcode.cn/problems/liang-ge-lian-biao-de-di-yi-ge-gong-gong-jie-dian-lcof/

public class Solution {
    Stack<ListNode> stack1 = new Stack<>();
    Stack<ListNode> stack2 = new Stack<>();
    ListNode        node1;
    ListNode        node2;
    ListNode        result;

    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        result = null;
        while (headA != null) {
            stack1.push(headA);
            headA = headA.next != null ? headA.next : null;
        }
        while (headB != null) {
            stack2.push(headB);
            headB = headB.next != null ? headB.next : null;
        }
        while (!stack1.isEmpty() && !stack2.isEmpty()) {
            node1 = stack1.pop();
            node2 = stack2.pop();
            if (node1 != node2) {
                return result;
            }
            result = node1;
        }
        return result;
    }
}

5 综合能力

面试题53-1:在排序数组中查找数字1

https://leetcode.cn/problems/zai-pai-xu-shu-zu-zhong-cha-zhao-shu-zi-lcof/

class Solution {
    public static int search(int[] nums, int target) {
        if (nums.length == 0) {
            return 0;
        }
        Arrays.sort(nums);
        int left = 0;
        int right = nums.length - 1;
        int mid = left + (right - left) / 2;
        int key = binarySearch(nums, target, left, right, mid);
        if (key == -1) {
            return 0;
        } else {
            int count = 0;
            int cIndex = key;
            while (cIndex >= left) {
                if (nums[cIndex] == target) {
                    count++;
                    cIndex--;
                } else {
                    break;
                }
            }
            cIndex = key + 1;
            while (cIndex <= right) {
                if (nums[cIndex] == target) {
                    count++;
                    cIndex++;
                } else {
                    break;
                }
            }
            return count;
        }
    }

    public static int binarySearch(int[] nums, int target, int left, int right, int mid) {
        if (left > right) {
            return -1;
        }
        if (nums[mid] == target) {
            return mid;
        }
        if (nums[mid] > target) {
            right = mid - 1;
            mid = left + (right - left) / 2;
            return binarySearch(nums, target, left, right, mid);
        }
        if (nums[mid] < target) {
            left = mid + 1;
            mid = left + (right - left) / 2;
            return binarySearch(nums, target, left, right, mid);
        }
        return -1;
    }
}

面试题53-2:0~n-1中缺失的数字

https://leetcode.cn/problems/que-shi-de-shu-zi-lcof/

class Solution {
    public int missingNumber(int[] nums) {
        if (nums[0] != 0) {
            return 0;
        }
        int sub;
        for (int i = 0; i < nums.length - 1; i++) {
            sub = nums[i + 1] - nums[i];
            if (sub == 2) {
                return nums[i] + 1;
            }
        }
        return nums.length;
    }
}

面试题54:二叉搜索树的第k大节点

https://leetcode.cn/problems/er-cha-sou-suo-shu-de-di-kda-jie-dian-lcof/

class Solution {
    int      count = Integer.MIN_VALUE;
    TreeNode tn;

    public int kthLargest(TreeNode root, int k) {
        search(root, k);
        return tn.val;
    }

    public void search(TreeNode node, int k) {
        if (node == null) {
            return;
        }
        if (node.right == null && count == Integer.MIN_VALUE) {
            count = 1;
        }
        search(node.right, k);
        if (count == k) {
            tn = node;
        }
        count++;
        search(node.left, k);
    }
}

面试题55-1:二叉树的深度

https://leetcode.cn/problems/er-cha-shu-de-shen-du-lcof/

class Solution {
    Map<TreeNode, Integer> map      = new HashMap<>();
    int                    maxLevel = Integer.MIN_VALUE;

    public int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        dfs(root, 1);
        return maxLevel;
    }

    public void dfs(TreeNode node, int level) {
        if (map.containsKey(node)) {
            return;
        }
        map.put(node, level);
        if (maxLevel < level) {
            maxLevel = level;
        }
        if (node.left != null) {
            dfs(node.left, level + 1);
        }
        if (node.right != null) {
            dfs(node.right, level + 1);
        }
    }
}

面试题55-2:平衡二叉树

https://leetcode.cn/problems/ping-heng-er-cha-shu-lcof/

class Solution {
    Map<TreeNode, Integer> map = new HashMap<>(); // 记录从每个节点到叶子节点的树高

    public boolean isBalanced(TreeNode root) {
        if (dfs(root) == -1) {
            return false;
        } else {
            return true;
        }
    }

    public int dfs(TreeNode node) {
        if (node == null) {
            return 0;
        }
        if (map.containsKey(node)) {
            return map.get(node);
        }
        int lHeigth = dfs(node.left);
        int rHeigth = dfs(node.right);
        if (lHeigth == -1 || rHeigth == -1) {
            return -1;
        }
        if (lHeigth - rHeigth > 1 || lHeigth - rHeigth < -1) {
            return -1;
        }
        lHeigth++;
        rHeigth++;
        map.put(node, bigger(lHeigth, rHeigth));
        return map.get(node);
    }

    public int bigger(int left, int right) {
        if (left >= right) {
            return left;
        } else {
            return right;
        }
    }
}

面试题56-1:数组中数字出现的次数

https://leetcode.cn/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof/

class Solution {
    public int[] singleNumbers(int[] nums) {
        // 显然,nums.length 大于等于2
        int xor = nums[0];
        for (int i = 1; i < nums.length; i++) {
            xor = xor ^ nums[i];
        }
        int n = 0;
        while (xor != 0) {
            xor = xor >> 1;
            n++;
        }
        int left = 0;
        int right = nums.length - 1;
        int tmp;
        while (left <= right) {
            if (!indexNIs1(nums[left], n)) {
                left++;
                continue;
            }
            if (indexNIs1(nums[right], n)) {
                right--;
                continue;
            }
            tmp = nums[left];
            nums[left] = nums[right];
            nums[right] = tmp;
            left++;
            right--;
        }
        int mid = 0;
        for (int i = 0; i < nums.length; i++) {
            if (indexNIs1(nums[i], n)) {
                mid = i;
                break;
            }
        }
        int result1 = nums[0];
        for (int i = 1; i < mid; i++) {
            result1 = result1 ^ nums[i];
        }
        int result2 = nums[mid];
        for (int i = mid + 1; i < nums.length; i++) {
            result2 = result2 ^ nums[i];
        }
        return new int[] { result1, result2 };
    }

    public boolean indexNIs1(int num, int n) {
        return (num >> (n - 1)) % 2 == 1;
    }
}

面试题56-2:数组中数字出现的次数II

https://leetcode.cn/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-ii-lcof/

class Solution {
    public int singleNumber(int[] nums) {
        if (nums.length == 0) {
            return 0;
        }
        Arrays.sort(nums);
        int tmp = Integer.MAX_VALUE;
        boolean already = true;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] != tmp && already) {
                tmp = nums[i];
                already = false;
                continue;
            }
            if (nums[i] == tmp) {
                already = true;
            }
        }
        return tmp;
    }
}

面试题57-1:和为s的两个数字

https://leetcode.cn/problems/he-wei-sde-liang-ge-shu-zi-lcof/

class Solution {
    public int[] twoSum(int[] nums, int target) {
        Arrays.sort(nums);
        int p1 = 0;
        int p2 = nums.length - 1;
        while (p1 < p2) {
            if (target == nums[p1] + nums[p2]) {
                return new int[] { nums[p1], nums[p2] };
            }
            if (target > nums[p1] + nums[p2]) {
                p1++;
            } else {
                p2--;
            }
        }
        return new int[0];
    }
}

面试题57-2:和为s的连续正数序列

https://leetcode.cn/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof/

class Solution {
    public int[][] findContinuousSequence(int target) {
        // 求最大序列长度times
        int sum = 0;
        int times = 0;
        while (sum < target) {
            times++;
            sum = sum + times;
        }
        if (sum != target) {
            times--;
        }

        // 求满足要求的序列长度
        List<Integer> list = new ArrayList<>();
        for (int i = 2; i <= times; i++) {
            if (i % 2 == 0 && target % (target / i + target / i + 1) == 0) {
                list.add(i);
            }
            if (i % 2 == 1 && target % i == 0) {
                list.add(i);
            }
        }

        // 按满足要求的序列长度,对target进行拆分
        int[][] result = new int[list.size()][];
        for (int j = 0; j < list.size(); j++) {
            int tmp = list.get(j);
            int[] array = new int[tmp];

            if (tmp % 2 == 0) {
                int base = target / tmp;
                int half = tmp / 2;
                for (int k = 0; k < array.length; k++) {
                    array[k] = base - half + 1 + k;
                }
            }

            if (tmp % 2 == 1) {
                int base = target / tmp;
                int half = tmp / 2;
                for (int k = 0; k < array.length; k++) {
                    array[k] = base - half + k;
                }
            }
            result[list.size() - 1 - j] = array;
        }

        return result;
    }
}

面试题58-1:翻转单词顺序

https://leetcode.cn/problems/fan-zhuan-dan-ci-shun-xu-lcof/

class Solution {
    public String reverseWords(String s) {
        if ("".equals(s)) {
            return "";
        }
        String[] strings = s.split(" ");
        StringBuilder sb = new StringBuilder();
        for (int i = strings.length - 1; i >= 0; i--) {
            if (!"".equals(strings[i])) {
                sb.append(strings[i] + " ");
            }
        }
        return sb.toString().trim();
    }
}

面试题58-2:左旋转字符串

https://leetcode.cn/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/

class Solution {
    public String reverseLeftWords(String s, int n) {
        if (n >= s.length()) {
            return s;
        }
        String s1 = s.substring(0, n);
        String s2 = s.substring(n);
        return s2 + s1;
    }
}

面试题61:扑克牌中的顺子

https://leetcode.cn/problems/bu-ke-pai-zhong-de-shun-zi-lcof/

class Solution {
    Set<Integer> set = new HashSet<>();

    public boolean isStraight(int[] nums) {
        int max = Integer.MIN_VALUE;
        int min = Integer.MAX_VALUE;
        int count0 = 0;
        int tmp;
        for (int i = 0; i < nums.length; i++) {
            tmp = nums[i];
            if (tmp < 0 || tmp > 13) {
                return false;
            }
            if (tmp != 0) {
                if (set.contains(tmp)) {
                    return false;
                }
                set.add(tmp);
                if (tmp > max) {
                    max = tmp;
                }
                if (tmp < min) {
                    min = tmp;
                }
            } else {
                count0++;
                if (count0 == 5) {
                    return true;
                }
            }
        }
        return max - min + 1 <= 5;
    }
}

面试题63:股票的最大利润

https://leetcode.cn/problems/gu-piao-de-zui-da-li-run-lcof/

class Solution {
    public int maxProfit(int[] prices) {
        if (prices.length <= 1) {
            return 0;
        }
        int maxProfit = Integer.MIN_VALUE;
        int sum = 0;
        int[] subPrices = new int[prices.length - 1];
        for (int i = 0; i < prices.length - 1; i++) {
            subPrices[i] = prices[i + 1] - prices[i];
        }
        for (int j = 0; j < subPrices.length; j++) {
            sum = sum + subPrices[j];
            if (sum < 0) {
                sum = 0;
            }
            if (sum > maxProfit) {
                maxProfit = sum;
            }
        }
        return maxProfit;
    }
}

面试题64:求1+2+…+n

https://leetcode.cn/problems/qiu-12n-lcof/

class Solution {
    public int sumNums(int n) {
        int sum = 0;
        boolean bool = n > 0 && (sum = n + sumNums(n - 1)) > 0;
        return sum;
    }
}

面试题65:不用加减乘除做加法

https://leetcode.cn/problems/bu-yong-jia-jian-cheng-chu-zuo-jia-fa-lcof/

class Solution {
    public int add(int a, int b) {
        int sum;
        int carry;
        while (b != 0) {
            sum = a ^ b;
            carry = (a & b) << 1;
            a = sum;
            b = carry;
        }
        return a;
    }
}

面试题66:构建乘积数组

https://leetcode.cn/problems/gou-jian-cheng-ji-shu-zu-lcof/

class Solution {
    Map<Integer, Integer> map = new HashMap<>();

    public int[] constructArr(int[] a) {
        if (a.length == 0) {
            return new int[] {};
        }
        if (a.length == 1) {
            return new int[] { 1 };
        }
        int leftTotal = 1;
        int current = 0;
        int[] b = new int[a.length];
        while (current < a.length) {
            int rightTotal = 1;
            if (map.containsKey(current + 1)) {
                rightTotal = map.get(current + 1);
            } else {
                for (int i = a.length - 1; i > current; i--) {
                    rightTotal *= a[i];
                    map.put(i, rightTotal);
                }
            }
            b[current] = leftTotal * rightTotal;
            leftTotal *= a[current];
            current++;
        }
        return b;
    }
}

面试题68-1:二叉搜索树的最近公共祖先

https://leetcode.cn/problems/er-cha-sou-suo-shu-de-zui-jin-gong-gong-zu-xian-lcof/

class Solution {
    TreeNode current;
    TreeNode result;

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (p.val > q.val) {
            current = p;
            p = q;
            q = current;
        }
        current = root;
        work(current, p, q);
        return result;
    }

    public void work(TreeNode current, TreeNode p, TreeNode q) {
        if (current.val > p.val && current.val < q.val) {
            result = current;
        } else if (current.val == p.val) {
            result = p;
        } else if (current.val == q.val) {
            result = q;
        } else if (current.val > p.val && current.val > q.val) {
            work(current.left, p, q);
        } else if (current.val < p.val && current.val < q.val) {
            work(current.right, p, q);
        }
    }
}

面试题68-2:二叉树的最近公共祖先

https://leetcode.cn/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof/

class Solution {
    Stack<TreeNode> stack = new Stack<>();
    List<TreeNode>  path1 = new ArrayList<>();
    List<TreeNode>  path2 = new ArrayList<>();

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null) {
            return null;
        }
        dfs(root, p, q);
        TreeNode common = root;
        int index = 0;
        while (index < path1.size() && index < path2.size()) {
            if (path1.get(index) == path2.get(index)) {
                common = path1.get(index);
            }
            index++;
        }
        return common;
    }

    public void dfs(TreeNode node, TreeNode p, TreeNode q) {
        stack.push(node);
        if (node.val == p.val) {
            path1.addAll(stack);
        }
        if (node.val == q.val) {
            path2.addAll(stack);
        }
        if (node.left != null) {
            dfs(node.left, p, q);
        }
        if (node.right != null) {
            dfs(node.right, p, q);
        }
        stack.pop();
    }
}
  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值