剑指offer

数组中重复数字

public static int findRepeatNumber(int[] nums) {
        int length = nums.length;
        Map<Integer,Integer> map = new HashMap<>();
        for (int i=0;i<length;i++){
            map.put(i,0);
        }
        for (int item:nums){
            int a= map.get(item);
            if (a==1) return item;
            a++;
            map.put(item,a);
        }
        return -1;
    }

4二维数组中查找

public static boolean findNumberIn2DArray(int[][] matrix, int target) {
        if (matrix==null)return false;
        int rows = matrix.length;
        if (rows ==0) return false;
        int columns = matrix[0].length;
        if (matrix!=null && rows >0 && columns>0){
            int row = 0;
            int column = columns-1;
            while (row < rows && column >=0){
                if (target == matrix[row][column]){
                    return true;
                }else if (target>matrix[row][column]){
                    row++;
                }else if (target<matrix[row][column]){
                    column--;
                }
            }
        }
        return false;
    }

替换空格

public String replaceSpace(String s) {
        String a = s.replace(" ","%20");//注意String是不可变的
        return a;
    }

从尾到头打印链表

public int[] reversePrint(ListNode head) {
        LinkedList<Integer> linkedList = new LinkedList<>();
        ListNode listNode = head;
        while (listNode != null){
            linkedList.addFirst(listNode.val);
            listNode = listNode.next;
        }
        int[] ints = new int[linkedList.size()]; 
        int i=0;
        for (int item : linkedList){
            ints[i++] = item;
        }
        return ints;
    }

重建二叉树

public static TreeNode buildTree(int[] preorder, int[] inorder) {
        if (preorder ==null || preorder.length ==0)
            return null;
        Map<Integer,Integer> indexMap = new HashMap<>();
        int length = preorder.length;
        for (int i=0;i<length;i++){
            indexMap.put(inorder[i],i);
        }


        TreeNode hand =buildTree(preorder,0,length-1,inorder,0,length-1,indexMap);
        return hand;
    }
    public static TreeNode buildTree(int[] preorder,int preorderStart,int preorderEnd,int[] inorder,int inorderstart,int inorderEnd,Map<Integer,Integer> indexMap)
    {
        if (preorderStart > preorderEnd){
            return null;
        }
        int rootval = preorder[preorderStart];
        TreeNode root = new TreeNode(rootval);
        if (preorderStart == preorderEnd){
            return root;
        }else {
            int rootindex = indexMap.get(rootval);
            int leftNodes = rootindex - inorderstart;
            int rightNode = inorderEnd - rootindex;
            TreeNode leftSubtree = buildTree(preorder,preorderStart+1,preorderStart+leftNodes,inorder,inorderstart,rootindex-1,indexMap);
            TreeNode rightSbutree = buildTree(preorder,preorderEnd-rightNode+1,preorderEnd,inorder,rootindex+1,inorderEnd,indexMap);
            root.left = leftSubtree;
            root.right = rightSbutree;
            return root;

        }
    }

斐波那契

public static int fib(int n) {
        ArrayList<Integer> list = new ArrayList<>();

        list.add(0);
        list.add(1);
        if (n==0) return 0;
        if (n==1) return 1;
        for (int i=2;i<=n;i++){
            Integer integer = list.get(i - 1);
            Integer integer1 = list.get(i - 2);
            list.add((integer + integer1)%1000000007);//这里需要取余
        }
        return list.get(n);
    }

青蛙跳台

public int numWays(int n) {
        List<Integer> arrayList = new ArrayList<>();
        arrayList.add(0);
        arrayList.add(1);
        arrayList.add(2);
        if (n==0) return 1;
        if (n==1) return 1;
        if (n==2) return 2;
        for (int i=3;i<=n;i++){
            Integer integer = arrayList.get(i - 1);
            Integer integer1 = arrayList.get(i - 2);
            Integer a = (integer + integer1)%1000000007;
            arrayList.add(a);
        }
        return arrayList.get(n);
    }

旋转数组的最小值

public int minArray(int[] numbers) {
        int length = numbers.length;
        for (int i=length-1; i>0; i--){
            if (numbers[i] < numbers[i-1])
                return numbers[i];
        }
        return numbers[0];
    }

矩阵中的路径

public static boolean exist(char[][] board, String word) {
        int rows = board.length;
        int columns = board[0].length;
        boolean[][] flag = new boolean[rows][columns];
        char[] chars = word.toCharArray();
        for (int i=0;i<rows;i++){
            for (int j=0;j<columns;j++){
                if (board[i][j] == chars[0]){
                    if (play(board,flag,chars,0,i,j)) {
                        return true;
                    }
                }

            }
        }
        return false;
    }
    public static boolean play(char[][] board,boolean[][] flag,char[] chars,int index,int i,int j){
        if (i >= board.length || i< 0 || j >= board[0].length || j < 0 || board[i][j] != chars[index] || flag[i][j])
            return false;
        if (index == chars.length-1) return true;
        flag[i][j] = true;
        boolean res = play(board,flag,chars,index+1,i,j+1)||
                play(board,flag,chars,index+1,i,j-1)||
                play(board,flag,chars,index+1,i+1,j)||
                play(board,flag,chars,index+1,i-1,j);
        flag[i][j] = false;//关键  将返回路径重置
        return res;
    }

机器人的运动范围

public int movingCount(int m, int n, int k) {
        if (k == 0){
            return 1;
        }
        boolean[][] flag = new boolean[m][n];
        int ans = 1;
        flag[0][0] = true;
        for (int i=0;i < m;i++){
            for (int j=0;j < n;j++){
                if ((i == 0 && j == 0) || get(i)+get(j) > k ){
                    continue;
                }
                if (i - 1 >=0){
                    flag[i][j] |= flag[i-1][j];
                }
                if (j - 1 >= 0){
                    flag[i][j] |= flag[i][j - 1];
                }
                ans += flag[i][j] ? 1 : 0;
            }
        }
        return ans;
    }
    public int get(int x){
        int res=0;
        while (x != 0){
            res += x%10;
            x /=10;
        }
        return res;
    }

剪绳子

public int cuttingRope(int n) {//贪心算法
        if(n < 2) return 0;
        if (n == 2) return 1;
        if (n == 3) return 2;
        int timesOf3 = n / 3;
        if (n - timesOf3*3 ==1)
            timesOf3 -=1;
        int timesOf2 = (n - timesOf3*3) /2;
        return (int) (Math.pow(3,timesOf3)*Math.pow(2,timesOf2));
    }
public int cuttingRope(int n) {//动态规划
        if (n < 2) return 0;
        if (n == 2) return 1;
        if (n == 3) return 2;

        int[] products = new int[n+1];
        products[0] = 0;
        products[1] = 1;
        products[2] = 2;
        products[3] = 3;

        int max =0;
        for (int i = 4;i <= n;i++){
            max = 0;
            for (int j = 1;j <= i/2;j++){
                int product = products[j]*products[i-j];
                if (max < product)
                    max = product;
                products[i] = max;
            }
        }
        return products[n];
    }

二进制中的1的个数

public int hammingWeight(int n) {//
        String s = Integer.toBinaryString(n);
        char[] chars = s.toCharArray();
        int num = 0;
        for (char item:chars){
            if (item =='1') num++;
        }
        return num;
    }
public static int hammingWeight(int n) {
        int res = 0;
        while(n != 0) {
            res += n & 1;
            n =n >>> 1;
        }
        return res;
    }

数值的整数次方

public static double myPow(double x, int n) {//很笨
        if (x == 1 && n > 0)
            return 1;
        if (x == 2 && n ==-2147483648)
            return 0;
        if (x == -1 && n == 2147483647)
            return -1;
        boolean flag = false;
        if (n < 0) {
            n = -n;
            flag = true;
        }
        double res = 1;
        for (int i=0;i<n;i++){
            res *= x;
        }
        return flag ? 1/res:res;
    }
public static double myPow(double x, int n) {
        if (x == 0) return 0;
        boolean flag = false;
        if (n < 0){
            flag = true;
            n = -n;
        }

        double pow = pow(x, n);
        return flag ? 1/pow : pow;
    }
    public static double pow(double x, int n){
        if (n == 0) return 1;
        if (n == 1) return x;

        double pow = pow(x, n >>> 1);
        pow *= pow;
        if ((n & 0x1) ==1)//为奇数
            pow *= x;
        return pow;
    }

链表中删除节点

public ListNode deleteNode(ListNode head, int val) {
        if (head.val == val){
            head = head.next;
            return head;
        }
        ListNode r = head;
        ListNode l = head.next;
        while (l.val != val){
            r = r.next;
            l = l.next;
            if (l == null) return head;
        }
        r.next = l.next;
        return head;
        
    }

调整数组顺序 奇数前 偶数后

public static int[] exchange(int[] nums) {
        int left =0;
        int right = nums.length -1;
        while (left < right){
            if ((nums[left] & 1) == 1){
                left++;
               continue;
            }
            if ((nums[right] & 1) == 0){
                right--;
                continue;
            }
            int item = nums[left];
            nums[left] = nums[right];
            nums[right] = item;
        }
        return nums;
    }

链表中倒数第k个节点

public ListNode getKthFromEnd(ListNode head, int k) {
        ListNode h = head;
        int length  =0;
        while (h != null){
            h = h.next;
            length++;
        }
        h = head;
        int res = length - k;
        for (int i =0 ;i < res ;i++){
            h = h.next;
        }
        return h;
    }

反转链表

public ListNode reverseList(ListNode head) {
        if (head == null) return head;
        ListNode h  = new ListNode(head.val);
        head = head.next;
        while (head != null){
             ListNode item = new ListNode(head.val);
             item.next = h;
             h = item;
             head = head.next;
        }
        return h;
    }

合并两个排序的链表

public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode left = l1;
        ListNode right = l2;
        ListNode res;
        if (l1 == null){
            return l2;
        }else if (l2 == null){
            return l1;
        }
        if (l1.val < l2.val){
            res = new ListNode(left.val);
            left = left.next;
        }else {
            res = new ListNode(right.val);
            right = right.next;
        }
        ListNode res1 = res;
        while (left != null && right != null){
            if (left.val < right.val){
                res1.next = left;
                res1 = left;
                left = left.next;
            }else {
                res1.next = right;
                res1 = right;
                right = right.next;
            }
        }
        if (left == null){
            res1.next = right;
        }else {
            res1.next = left;
        }

        return res;
    }

树的子结构

public boolean isSubStructure(TreeNode A, TreeNode B) {
        if (A == null || B == null) return false;
        return play(A,B) || isSubStructure(A.left,B) | isSubStructure(A.right,B);
    }

    public boolean play(TreeNode A,TreeNode B){
        if(B == null) return true;
        if (A == null || A.val != B.val) return false; // 判断顺序不可调换
        return play(A.left,B.left) && play(A.right,B.right);
    }

二叉树的镜像

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

    public TreeNode play(TreeNode root){
        if (root == null) return null;
        item = root.left;
        root.left = root.right;
        root.right = item;
        play(root.left);
        play(root.right);
        return root;
    }
public TreeNode mirrorTree(TreeNode root) {
        if (root == null) return null;
        TreeNode item = root.left;
        root.left = mirrorTree(root.right);
        root.right = mirrorTree(item);
        return root;
    }
public TreeNode mirrorTree(TreeNode root) {
        if (root == null) return null;
        LinkedList<TreeNode> linkedList = new LinkedList<>();
        linkedList.add(root);
        while (!linkedList.isEmpty()){
            TreeNode node = linkedList.pop();
            if (node.left != null) linkedList.add(node.left);
            if (node.right != null) linkedList.add(node.right);
            TreeNode item = node.left;
            node.left = node.right;
            node.right = item;
        }
        return root;
    }

对称二叉树

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

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

从上到小打印二叉树 BFS广度优先算法

 public int[] levelOrder(TreeNode root) {

        if (root == null) return new int[0];
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        ArrayList<Integer> ans = new ArrayList<>();
        queue.add(root);
        while (!queue.isEmpty()){
            TreeNode node = queue.poll();
            ans.add(node.val);
            if (node.left != null) queue.add(node.left);
            if (node.right != null) queue.add(node.right);
        }
        int[] res = new int[ans.size()];
        for (int i =0 ; i < ans.size();i++){
            res[i] = ans.get(i);
        }
        return res;
    }

2

    public List<List<Integer>> levelOrder(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
        List<List<Integer>> res = new ArrayList<>();
        if (root != null)  queue.add(root);
        while (!queue.isEmpty()){
            List<Integer> tmp = new ArrayList<>();
            for (int i = queue.size(); i > 0 ;i--){
                TreeNode node = queue.poll();
                tmp.add(node.val);
                if (node.left != null) queue.add(node.left);
                if (node.right != null) queue.add(node.right);
            }
            res.add(tmp);
        }
        return res;
    }

3

    public List<List<Integer>> levelOrder(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
        List<List<Integer>> list = new LinkedList<>();
        if (root != null) queue.add(root);
        boolean flag = true;
        while (!queue.isEmpty()){
            LinkedList<Integer> res = new LinkedList<>();
            for (int i = queue.size(); i > 0 ;i--){
                TreeNode node = queue.poll();
                if (flag) {
                    res.addLast(node.val);
                }else {
                    res.addFirst(node.val);
                }
                if (node.left != null) queue.add(node.left);
                if (node.right != null) queue.add(node.right);
            }
            list.add(res);
            if (flag) flag = false;
            else flag = true;
        }
        return list;
    }

二叉搜索树的后序遍历队列

public boolean verifyPostorder(int[] postorder) {
        return recur(postorder,0,postorder.length-1);
    }
    boolean recur(int[] postorder,int i , int j){
        if (i >= j) return true;
        int p = i;
        while (postorder[p] < postorder[j]) p++;
        int m = p-1;
        while (postorder[p] > postorder[j]) p++;
        return p == j && recur(postorder,i,m) && recur(postorder,m+1,j-1);
    }

二叉树中和为某一值的路径

    LinkedList<List<Integer>> res = new LinkedList<>();
    LinkedList<Integer> path = new LinkedList<>();

    public List<List<Integer>> pathSum(TreeNode root, int sum) {
        recur(root,sum);
        return res;

    }
    public void recur(TreeNode root,int tar){
        if (root == null) return;
        path.addLast(root.val);
        tar -= root.val;
        if (tar ==0 && root.left == null && root.right == null){
            res.add(new LinkedList<>(path));
        }
        recur(root.left,tar);
        recur(root.right,tar);
        path.removeLast();
    }

复杂链表的复制

public Node copyRandomList(Node head) {
        if (head == null) return null;
        copy(head);
        random(head);
        return reList(head);
    }
    public void copy(Node head){
        while (head != null){
            Node clone = new Node(head.val);
            Node nextHead = head.next;
            head.next = clone;
            clone.next = nextHead;
            head = nextHead;
        }
    }
    public void random(Node head){
        while (head != null){
            Node nextNode = head.next;
            if (head.random != null){
                Node nextRandom = head.random;
                nextNode.random = nextRandom.next;
            }

            head = nextNode.next;
        }
    }
    public Node reList(Node head){
        Node h  = head.next;
        head.next = h.next;
        head = head.next;
        Node item = h;
        while (head != null){
            item.next = head.next;
            head.next = head.next.next;
            head = head.next;
            item = item.next;
        }
        return h;
    }
    public Node copyRandomList(Node head) {
        if (head == null) return null;
        HashMap<Node ,Node> hashMap = new HashMap<>();
        Node item = head;
        while (item != null){
            hashMap.put(item,new Node(item.val));
            item = item.next;
        }
        item = head;
        while (item != null){
            hashMap.get(item).next = hashMap.get(item.next);
            hashMap.get(item).random = hashMap.get(item.random);
            item = item.next;
        }
        return hashMap.get(head);
    }

二叉搜索树与双向链表

    Node pre , 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 cur){
        if (cur == null) return;
        dfs(cur.left);
        if (pre != null) pre.right = cur;
        else head = cur;
        cur.left = pre;
        pre = cur;
        dfs(cur.right);

    }

序列化二叉树

    // Encodes a tree to a single string.
    public String serialize(TreeNode root) {
        if (root == null)
            return "#";
        Queue<TreeNode> queue = new LinkedList<>();
        StringBuilder res = new StringBuilder();

        queue.add(root);
        while (!queue.isEmpty()){
            TreeNode node = queue.poll();
            if (node == null){
                res.append("#,");
                continue;
            }
            res.append(node.val+",");
            queue.add(node.left);
            queue.add(node.right);
        }
        return res.toString();
    }

    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {
        if (data == "#"){
            return null;
        }
        Queue<TreeNode> queue = new LinkedList<>();

        String[] values = data.split(",");
        TreeNode root = new TreeNode(Integer.parseInt(values[0]));

        queue.add(root);
        for (int i=1;i < values.length;i++){
            TreeNode node = queue.poll();

            if (!"#".equals(values[i])){
                TreeNode left = new TreeNode(Integer.parseInt(values[i]));
                node.left = left;
                queue.add(left);
            }
            if (!"#".equals(values[++i])){
                TreeNode right = new TreeNode(Integer.parseInt(values[i]));
                node.right = right;
                queue.add(right);
            }
        }
        return root;

    }

二叉树的深度

public int maxDepth(TreeNode root) {
        if (root == null) return 0;
        return Math.max(maxDepth(root.left),maxDepth(root.right))+1;
    }
public int maxDepth(TreeNode root) {
        if (root == null) return 0;
        List<TreeNode> queue = new LinkedList<>(),tmp;
        queue.add(root);
        
        int depth = 0;
        while (!queue.isEmpty()){
            tmp = new LinkedList<>();
            for (TreeNode item : queue){
                if (item.left != null) tmp.add(item.left);
                if (item.right != null) tmp.add(item.right);
            }
            queue = tmp;
            depth++;
        }
        return depth;
    }

二叉搜索树的第k大的数

	int res , k;
    public int kthLargest(TreeNode root, int k) {//中序遍历的后续遍历
        this.k = k;
        max(root);
        return res;
    }
    public void  max(TreeNode root){
        if (root == null) return;
        max(root.right);
        if (k == 0) return;
        if (--k == 0) res = root.val;
        max(root.left);
    }

平衡二叉树

	public boolean isBalanced(TreeNode root) {
        if (root == null){
            return true;
        }else {
            return Math.abs(height(root.left) - height(root.right)) <= 1 && isBalanced(root.left) && isBalanced(root.right);
        }
    }
    public int height(TreeNode root){
        if (root == null){
            return 0;
        }else {
           return Math.max(height(root.left),height(root.right))+1;
        }

    }

二叉搜索树的最近公共祖先

	//迭代   两个节点在同一边,则遍历这一边,如果在异侧则返回
	public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        while (root != null){
            if (root.val < p.val && root.val < q.val)
                root = root.right;
            else if (root.val > p.val && root.val > q.val)
                root = root.left;
            else break;
        }
        return root;
    }
	//递归 如果在root节点的同侧,则递归这一侧,否则返回
	public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root.val < p.val && root.val < q.val)
            return lowestCommonAncestor(root.right,p,q);
        if (root.val > p.val && root.val > q.val)
            return lowestCommonAncestor(root.left,p,q);
        return root;
    }

二叉树的最近公共祖先

 public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null) return null;
        if (root == p || root == q) return root;
        TreeNode left = lowestCommonAncestor(root.left,p,q);
        TreeNode right = lowestCommonAncestor(root.right,p,q);
        if (left == null) return right;// 如果在左子树中 p和 q都找不到,则 p和 q一定都在右子树中,右子树中先遍历到的那个就是最近公共祖先(一个节点也可以是它自己的祖先)
        else if (right == null) return left;// 否则,如果 left不为空,在左子树中有找到节点(p或q),这时候要再判断一下右子树中的情况,如果在右子树中,p和q都找不到,则 p和q一定都在左子树中,左子树中先遍历到的那个就是最近公共祖先(一个节点也可以是它自己的祖先)
        else  return root;//否则,当 left和 right均不为空时,说明 p、q节点分别在 root异侧, 最近公共祖先即为 root
    }

!@#¥%……&*()——+12.12.22

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值