Sword finger Offer (java answer)

Posted by blt2589 on Sun, 14 Jun 2020 03:19:41 +0200

Reprint website: http://blog.csdn.net/sinat_29912455/article/details/51137349

Sword finger Offer (java answer)

3. Finding in 2D array

Title Description
In a two-dimensional array, each row is sorted in ascending order from left to right, and each column is sorted in ascending order from top to bottom. Please complete a function, input such a two-dimensional array and an integer to determine whether the array contains the integer.

1 2 8 9
2 4 9 12
4 7 10 13
6 8 11 15

Idea: from the top right corner, if small, go down, delete a row, if large, go left, delete a column

/*
Using the law that two-dimensional array increases from top to bottom and from left to right,
Then select the element a[row] [col] in the upper right or lower left corner to compare with target,
When target is smaller than element a[row] [col], then target must be to the left of the row in element a,
col --;
When target is greater than element a[row][col], then target must be under the column of element a,
row + +;
*/
public class Solution {
    public boolean Find(int [][] array,int target) {
        int row=0;
        int col=array[0].length-1;
        while(row<=array.length-1&&col>=0){
            if(target==array[row][col])
                return true;
            else if(target>array[row][col])
                row++;
            else
                col--;
        }
        return false; 
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

4,Replace space

Title Description
//Please implement a function to replace the space in a string with "% 20". For example, when the string is We Are Happy, the replaced string is We%20Are%20Happy.

Idea: first, traverse the characters once, count the number of spaces, and then calculate the total length after replacement. Then load the string from the back to the front. If you find a space, replace it by 20%

/*
Question 1: replace string. Do you want to replace the original string or create a new string to replace it!
Question 2: in the current string replacement, how to replace it more efficiently (regardless of the existing replacement method in java).
      Replace from front to back. The characters behind should move back and forth. They need to move many times, so the efficiency is low
      From the back to the front, first calculate how much space is needed, then move from the back to the front, then each character only moves once, which is more efficient.
*/
public class Solution {
    public String replaceSpace(StringBuffer str) {
        int spacenum = 0;//spacenum is the number of calculated spaces
        for(int i=0;i<str.length();i++){
            if(str.charAt(i)==' ')
                spacenum++;
        }
        int indexold = str.length()-1; //indexold is the str subscript before replacement
        int newlength = str.length() + spacenum*2;//Calculate str length after space converted to% 20
        int indexnew = newlength-1;//indexold is str subscript after replacing space with% 20
        str.setLength(newlength);//Increase the length of str to the length after conversion to% 20 to prevent the subscript from crossing the boundary
        for(;indexold>=0 && indexold<newlength;--indexold){ 
                if(str.charAt(indexold) == ' '){  //
                str.setCharAt(indexnew--, '0');
                str.setCharAt(indexnew--, '2');
                str.setCharAt(indexnew--, '%');
                }else{
                    str.setCharAt(indexnew--, str.charAt(indexold));
                }
        }
        return str.toString();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

5. Print linked list from end to end

Title Description:
Enter a linked list and print the values of each node of the linked list from the end to the end.

Idea 1: stack

/**
*    public class ListNode {
*        int val;
*        ListNode next = null;
*        ListNode(int val) {
*            this.val = val;
*        }
*    }
*/
import java.util.Stack;
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        if(listNode == null){
            ArrayList list = new ArrayList();
            return list;
        }
        Stack<Integer> stk = new Stack<Integer>();
        while(listNode != null){
            stk.push(listNode.val);
            listNode = listNode.next;
        }
        ArrayList<Integer> arr = new ArrayList<Integer>();
        while(!stk.isEmpty()){
            arr.add(stk.pop());
        }
        return arr;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

Train of thought 2: recursion

public class Solution {
    public void printListFromTailToHead(ListNode listNode) {
      if(listNode != null){
            if(listNode.next != null){
                printListFromTailToHead(listNode.next);
            }
           System.out.print(""+listNode.var);
        }

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

6. Reconstruction of binary tree

Topic Description: given the middle order and the front order, please rebuild the binary tree

/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        TreeNode root=reConstructBinaryTree(pre,0,pre.length-1,in,0,in.length-1);
        return root;
    }
    //Preorder ergodic {1,2,4,7,3,5,6,8} and middle order ergodic sequence {4,7,2,1,5,3,8,6}
    private TreeNode reConstructBinaryTree(int [] pre,int startPre,int endPre,int [] in,int startIn,int endIn) {  
        if(startPre>endPre||startIn>endIn)
            return null;
        TreeNode root=new TreeNode(pre[startPre]);
        for(int i=startIn;i<=endIn;i++)
            if(in[i]==pre[startPre]){
                root.left=reConstructBinaryTree(pre,startPre+1,startPre+i-startIn,in,startIn,i-1);  //Pay attention to the position of pre, use offset instead of i, because i is changing              
                root.right=reConstructBinaryTree(pre,i-startIn+startPre+1,endPre,in,i+1,endIn);
            }                 
        return root;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

Extension: finding the preorder from known middle order and post order

package com.zhuang.tree;

public class Main {

     public static class TreeNode {
          int val;
          TreeNode left;
          TreeNode right;
          TreeNode(int x) { val = x; }
      }

     public static TreeNode reConstructBinaryTree(int [] post,int [] in) {
            TreeNode root=reConstructBinaryTree(post,0,post.length-1,in,0,in.length-1);
            return root;
        }


        private static TreeNode reConstructBinaryTree(int [] post,int startPost,int endPost,int [] in,int startIn,int endIn) {

            if(startPost>endPost||startIn>endIn)
                return null;

            TreeNode root=new TreeNode(post[endPost]);

            for(int i=startIn;i<=endIn;i++)
                if(in[i]==post[endPost]){
                    root.left=reConstructBinaryTree(post,startPost,startPost+i-startIn-1,in,startIn,i-1);
                    root.right=reConstructBinaryTree(post,startPost+i-startIn,endPost-1,in,i+1,endIn);
                }

            return root;
        }

        public static void preOrder(TreeNode root){
            if(root == null){
                return;
            }
            System.out.println(root.val);
            preOrder(root.left);
            preOrder(root.right);
        }

        public static void main(String[] args){
            int[] post = {2,4,3,1,6,7,5};
            int[] in = {1,2,3,4,5,6,7};
            TreeNode root = reConstructBinaryTree(post, in);
            preOrder(root);
        }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

7. Using two stacks to implement queues

Title Description
Two stacks are used to implement a queue, and the Push and Pop operations of the queue are completed. The element in the queue is of type int.

Idea: input stack to stack1, and output stack if stack2 is not empty. If it is empty, put all the contents of stack1 into stack2, and then output stack

import java.util.Stack;

public class Solution {
    Stack<Integer> stack1 = new Stack<Integer>();
    Stack<Integer> stack2 = new Stack<Integer>();

   public void push(int node) {
        stack1.push(node);
    }


   public int pop() {

       while(!stack2.isEmpty())
        {
            return stack2.pop();
        }

        while(!stack1.isEmpty())
        {
            stack2.push(stack1.pop());
        }

        return stack2.pop();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

8. Minimum number of rotation array

Title Description
To move the first elements of an array to the end of the array, we call it the rotation of the array.
Input a rotation of an increasing sort array, and output the minimum elements of the rotation array.
For example, array {3,4,5,1,2} is a rotation of {1,2,3,4,5} and the minimum value of the array is 1.
NOTE: all the given elements are greater than 0. If the array size is 0, please return 0.

import java.util.ArrayList;

public class Solution {
    /*
     * Pass in the de rotation array, and pay attention to the characteristics of the rotation array: 1. It contains two ordered sequences; 2. The decimal must be at the beginning of the second sequence; 3. The values of the previous sequence are > = the values of the latter sequence
     */

    // Using the idea of quick sorting and quick positioning range,
    public int minNumberInRotateArray(int[] array) {

        if (array == null || array.length == 0) {
            return 0;
        }
        int low = 0;//Point to the first
        int up = array.length - 1;//Point to the last
        int mid = low;

        // When the low and up pointers are adjacent, the minimum value is found, that is
        // First value of right sequence

        while (array[low] >= array[up]) {
            if (up - low == 1) {
                mid = up;
                break;
            }
            // If the values of low, up and mid subscripts are exactly the same
            // For example: {1,1,1,0,1} rotation array
            if (array[low] == array[up] && array[mid] == array[low])
                return MinInOrder(array);
            mid = (low + up) / 2;
            // In this case, array[mid] is still in the left sequence
            if (array[mid] >= array[low])
                low = mid;// Note that it cannot be written as low=mid+1;
            // In this case, array[mid] is still in the right sequence
            else if (array[mid] <= array[up])
                up = mid;
        }

        return array[mid];

    }

    private int MinInOrder(int[] array) {
        // TODO Auto-generated method stub
        int min = array[0];
        for (int i = 1; i < array.length; i++) {
            if (array[i] < min) {
                min = array[i];

            }
        }
        return min;
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

9. Fibonacci series

Title Description
Everyone knows Fibonacci series. Now you need to input an integer n. please output the nth item of Fibonacci series.

Idea 1: recursion, simple but inefficient

public int Fibonacci(int n) {        
        if(n<=0)
            return 0;
        if(n==1)
            return 1;
        return Fibonacci(n-1) + Fibonacci(n-2); 
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Train of thought 2: circulation, O (N)

public class Solution {
    public int Fibonacci(int n) {
        int preNum=1;
        int prePreNum=0;
        int result=0;
        if(n==0)
            return 0;
        if(n==1)
            return 1;
        for(int i=2;i<=n;i++){
            result=preNum+prePreNum;
            prePreNum=preNum;
            preNum=result;
        }
        return result;

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

Extension 1: skip steps

A frog can jump up one or two steps at a time. Find out how many ways the frog can jump to an n-level step.

Thought: fiboracci number sequence, initial condition n=1: only one method, n=2: two methods
For the nth step, you can only jump from the n-1 or n-2 step, so
F(n) = F(n-1) + F(n-2)

Expansion 2: abnormal step

Title Description
A frog can jump up one step or two at a time It can also jump to level n. Find out how many ways the frog can jump to an n-level step.

Ideas:
Because there are n steps, the first step has n jumping methods: jump 1, jump 2, to jump n
If level 1 is skipped and level n-1 is left, then the remaining skip method is f(n-1)
Jump Level 2, n-2 is left, then the remaining jump method is f(n-2)
So f(n)=f(n-1)+f(n-2) + +f(1)
Because f(n-1)=f(n-2)+f(n-3) + +f(1)
So f(n)=2*f(n-1)
So f (n) = the (n-1) power of 2

public class Solution {
    public int JumpFloorII(int target) {
        if(target<=0)
            return 0;
        return 1<<(target-1);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

10. Number of 1 in binary

Title Description
Enter an integer and output the number of 1 in the binary representation of the number. Negative numbers are represented by complement.

The worst solution: because we need to consider the problem of negative numbers. If it is a negative number, because we need to ensure that we always input a negative number, the first digit is always 1, and eventually it will become 0xfffffff, causing a dead cycle

public class Solution {
public int  NumberOf1(int n) {
        int count= 0;
        int flag = 1;
        while (n!= 0){
            if ((n & 1) != 0){
                count++;      
            }
            n = n>>1;
        }
         return count;
     }    
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

Improved solution:

public class Solution {
public int  NumberOf1(int n) {
        int count= 0;
        int flag = 1;
        while (flag != 0){
            if ((n & flag) != 0){
                count++;      
            }
            flag  = flag << 1;
        }
         return count;
     }    
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

The best solution:

public class Solution {
    public int NumberOf1(int n) {
        int count = 0;
        while(n!= 0){
            count++;
            n = n & (n - 1);//Change the last 1 to 0 each time
         }
        return count;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

11. Integer power of value

Title Description
Given a floating-point base of type double and an integer of type int, exponent. Find the exponent power of base.

Train of thought 1: this problem mainly considers the boundary problem, which is not a comprehensive and efficient solution. Note: because there are errors in the computer representation of decimals (including float and double decimals), we can not directly use = = to judge whether two decimals are equal. If the absolute value of the difference between two decimals is very small, for example, it is less than 0.0000001, then they can be considered equal

public class Solution {
    public double Power(double base, int exponent) {
        double res = 0.0;
        if (equal(base, 0.0) && exponent < 0) {
            throw new RuntimeException("0 The negative power of is meaningless");
        }
        // The 0 power of 0 defined here is 1
        if (exponent == 0) {
            return 1.0;
        }
        if (exponent < 0) {
            res = powerWithExponent(1.0/base, -exponent);
        } else {
            res = powerWithExponent(base, exponent);
        }
        return res;
    }

    private double powerWithExponent(double base, int exponent) {
        double res = 1.0;
        for (int i = 1; i <= exponent; i++) {
            res = res * base;
        }
        return res;
    }

    // Judge data of double type
    private boolean equal(double num1, double num2) {
        if (Math.abs(num1 - num2) < 0.0000001) {
            return true;
        }
        return false;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

Idea 2: when n is even: A ^ n = a ^ n / 2 * a ^ n / 2;
N is odd, a^n = (a ^ (n-1) / 2) * (a ^ (n-1/2)) * a
So, if we optimize the multiplication, if it's the power of 32, it's equal to the power of 16 * the power of 16

 /*
    ** The part that optimizes multiplication
    */
    private double powerWithExponent(double base, int exponent) {
        if(exponent==0){
            return 1;
        }

        if(exponent==1){
            return base;
        }

       double result = powerWithExponent(base,exponent>>1);//Divide by 2 each time
       result*=result;//Finally multiply. If it's an odd number, multiply one

        //In the case of odd power, the final division of 2 and the remaining 1 should be multiplied by base
        if((exponent & 0x1)==1){
            result *= base;
        }
        return result;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

12. Print 1 to maximum n digits

Title Description: if n=3, print from 1 to 999

public class Solution {

    // ====================Method 1====================
    public static void Print1ToMaxOfNDigits(int n) {
        if (n <= 0)
            return;

        char[] number = new char[n];

        //Set each character to 0
        for (int i = 0; i < n; i++) {
            number[i] = '0';
        }

        while (!Increment(number)) {//If the addition overflows, exit, otherwise print the number
            PrintNumber(number);
        }

    }

    // The string number represents a number, increasing number by 1
    // Returns true if the addition overflows; otherwise, false
    public static boolean Increment(char[] number) {
        boolean isOverflow = false;//Overflow flag
        int nTakeOver = 0;//carry
        int nLength = number.length;

        for (int i = nLength - 1; i >= 0; i--) {//From back to front, last digit plus 1
            int nSum = number[i] - '0' + nTakeOver;
            if (i == nLength - 1)
                nSum++;

            if (nSum >= 10) {
                if (i == 0)
                    isOverflow = true;
                else {
                    nSum -= 10;
                    nTakeOver = 1;
                    number[i] = (char) ('0' + nSum);
                }
            } else {
                number[i] = (char) ('0' + nSum);
                break;
            }
        }

        return isOverflow;
    }

    // The string number represents a number, which has several zeros
    // Print this number and ignore the first 0
    public static void PrintNumber(char[] number) {
        boolean isBeginning0 = true;
        int nLength = number.length;

        //The idea of flag bit is printed from the first digit not 0, such as 000123, print123
        for (int i = 0; i < nLength; ++i) {
            if (isBeginning0 && number[i] != '0')
                isBeginning0 = false;

            if (!isBeginning0) {
                System.out.print(number[i]);
            }
        }
        System.out.println();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68

Train of thought 2: recursion is used, the code is simple, the train of thought is not easy to think about, and each bit is arranged from 0 to 9

public class Solution {

    // //Method 2: recursion====================
    public static void Print1ToMaxOfNDigits(int n) {
        if (n <= 0)
            return;

        char[] number = new char[n];

        for (int i = 0; i < 10; ++i) {
            number[0] = (char) (i + '0');
            Print1ToMaxOfNDigitsRecursively(number, n, 0);
        }

    }

    public static void Print1ToMaxOfNDigitsRecursively(char[] number, int length,int index) {
        if (index == length - 1) {
            PrintNumber(number);
            return;
        }

        for (int i = 0; i < 10; ++i) {
            number[index + 1] = (char) (i + '0');
            Print1ToMaxOfNDigitsRecursively(number, length, index + 1);
        }
    }

    // The string number represents a number, which has several zeros
    // Print this number and ignore the first 0
    public static void PrintNumber(char[] number) {
        boolean isBeginning0 = true;
        int nLength = number.length;

        // The idea of flag bit is to print from the first digit which is not 0, such as 000123, print123
        for (int i = 0; i < nLength; ++i) {
            if (isBeginning0 && number[i] != '0')
                isBeginning0 = false;

            if (!isBeginning0) {
                System.out.print(number[i]);
            }
        }
        System.out.println();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

13. Delete linked list nodes at O(1)

Give the order direction chain header pointer and a node pointer, and delete the chain node at O(1) time

/*
    For deleting a node, our common idea is to point the previous node of the node to the next node of the modified node
    */
    public void delete(Node head, Node toDelete){
        if(toDelete == null){
            return ;
        }
        if(toDelete.next != null){//Deleted node is not a tail node
            toDelete.val = toDelete.next.val;
            toDelete.next = toDelete.next.next;
        }else if(head == toDelete){//There is only one node in the linked list, and deleting the head node is also the tail node
            head = null;
        }else{ //When the deleted node is a tail node
            Node node = head;
            while(node.next != toDelete){//Find the penultimate node
                node = node.next;
            }
            node.next = null;
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

14. Adjust the array order so that the odd number precedes the even number

Title Description
Input an integer array, and implement a function to adjust the order of the numbers in the array, so that all the odd numbers are in the first half of the array, all the even numbers are in the second half of the array, and ensure the relative positions between the odd numbers and odd numbers, even numbers and even numbers are unchanged.

public class Solution {
    public void reOrderArray(int [] array) {
        //The part of annotation uses the algorithm of quick sorting, which is obviously unstable. Here we need to use merge sorting
        /*
        if(array.length == 0){
            return;
        }
        int high = array.length - 1;
        int low = 0;
        while(low < high){
            while(low < high && array[low] % 2 == 1){
                low ++;
            }
            while(low < high && array[high] % 2 == 0){
                high --;
            }
            int temp = array[low];
            array[low] = array[high];
            array[high] = temp;
        }*/

        //Using the idea of merging and sorting, because merging and sorting are stable
        int length = array.length;
        if(length == 0){
            return;
        }
        int[] des = new int[length];
        MergeMethod(array, des, 0,length - 1);
    }
    public void MergeMethod(int[] array, int [] des, int start, int end){
        if(start < end){
            int mid = (start + end) / 2;
            MergeMethod(array, des, start, mid);
            MergeMethod(array, des, mid + 1, end);
            Merge(array, des, start, mid, end);
        }
    }

    public void Merge(int[] array, int[] des, int start, int mid, int end){
        int i = start;
        int j = mid + 1;
        int k = start;
        while(i <= mid && array[i] % 2 == 1){
            des[k++] = array[i++];
        }
        while(j <= end && array[j] % 2 == 1){
            des[k++] = array[j++];
        }
        while(i <= mid){
            des[k++] = array[i++];
        }
        while(j <= end){
            des[k++] = array[j++];
        }

        for(int m = start; m <= end; m++){
            array[m] = des[m];
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60

15. The last k node in the list

Title Description
Input a list and output the k last node in the list.

Idea: for two pointers, first let the first pointer and the second pointer point to the head node, and then let the first pointer go (k-1) to the K node. Then the two pointers move backward at the same time. When the first node reaches the end, the second node is the last K node

/**
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode FindKthToTail(ListNode head,int k) {
        if(head==null||k<=0){
            return null;
        }
        ListNode pre=head;
        ListNode last=head;       
        for(int i=1;i<k;i++){
            if(pre.next!=null){
                pre=pre.next;
            }else{
                return null;
            }
        }
        while(pre.next!=null){
            pre = pre.next;
            last=last.next;
        }
        return last;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

16. Reverse linked list

Title Description
Input a list, reverse the list, output all elements of the list.

/*
 public class ListNode {
 int val;
 ListNode next = null;

 ListNode(int val) {
 this.val = val;
 }
 }*/
public class Solution {
    public ListNode ReverseList(ListNode head) {
        if (head == null)
            return null;
        if (head.next == null)
            return head;

        ListNode pPre = null;
        ListNode p = head;
        ListNode pNext = head.next;
        ListNode newHead = null;

        while (p != null) {
            pNext = p.next;//Be sure to record the nodes behind
            if (pNext == null)
                newHead = p;
            p.next = pPre;//The direction here has changed
            pPre = p;
            p = pNext;//Use the saved subsequent nodes as the p of the next loop

        }
        return newHead;

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

17. Merge two sorted linked lists

Title Description
Input two monotonically increasing linked lists, and output two synthesized linked lists. Of course, we need the synthesized linked lists to meet the monotone rule.

/**
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
     public ListNode Merge(ListNode list1, ListNode list2) {
         if(list1==null)
            return list2;
         else if(list2==null)
            return list1;
         ListNode mergeHead=null;
         if(list1.val<list2.val){
             mergeHead=list1;
             mergeHead.next=Merge(list1.next, list2);
         }
         else{
             mergeHead=list2;
             mergeHead.next=Merge(list1, list2.next);
         }
         return mergeHead;

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

Non recursive method:

public class Solution {
    public ListNode Merge(ListNode list1,ListNode list2) {
        if(list1==null&&list2==null)
            return null;
        if(list1==null&&list2!=null)
            return list2;
        if(list1!=null&&list2==null)
            return list1;
        ListNode head = null;
        if(list1.val<list2.val){
            head = list1;
            list1 = list1.next;
        }
        else{
            head = list2;
            list2 = list2.next;
        }
        ListNode cur = head;
        cur.next=null;
        while(list1!=null&&list2!=null){
            if(list1.val<list2.val){
                cur.next = list1;
                list1 = list1.next;
            }
            else{
                cur.next = list2;
                list2 = list2.next;
            }
            cur = cur.next;
            cur.next = null;
        }
        if(list1==null&&list2!=null){
            cur.next =list2;
        }else if(list2==null&&list1!=null){
            cur.next = list1;
        }
        return head;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

18. The substructure of a tree

Title Description
Input two binary trees a and B to determine whether B is a substructure of A.

Idea: first, traverse A tree, find out the same points of A root node and B root node, and then traverse whether the sub nodes of A and B are the same

/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}*/
public class Solution {
   public boolean HasSubtree(TreeNode root1,TreeNode root2) {
        if(root2==null) return false;
        if(root1==null && root2!=null) return false;       
        boolean flag = false;
        if(root1.val==root2.val){
            flag = isSubTree(root1,root2);
        }
        if(!flag){
            flag = HasSubtree(root1.left, root2);
        }
        if(!flag){
            flag = HasSubtree(root1.right, root2);
        }
        return flag;
    }

    private boolean isSubTree(TreeNode root1, TreeNode root2) {
        if(root2==null) return true;
        if(root1==null && root2!=null) return false;       
        if(root1.val==root2.val){
            return isSubTree(root1.left, root2.left) && isSubTree(root1.right, root2.right);
        }
        return false;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

19. Image of binary tree

Title Description
Operate the given binary tree and transform it into a mirror image of the source binary tree.
Image definition of binary tree: source binary tree
8
/ \
6 10
/ \ / \
5 7 9 11
Image binary tree
8
/ \
10 6
/ \ / \
11 9 7 5

Idea 1: use the stack structure (or queue structure) to stack the nodes in turn, and each node in the stack mirrors its child nodes

/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;
    }
}
*/

import java.util.Stack;

public class Solution {
    public void Mirror(TreeNode root) {
        if(root == null){
            return;
        }
        Stack<TreeNode> stack = new Stack<TreeNode>();
        stack.push(root);
        while(!stack.isEmpty()){
            TreeNode node = stack.pop();
            if(node.left != null||node.right != null){
                TreeNode temp = node.left;
                node.left = node.right;
                node.right = temp;
            }
            if(node.left!=null){
                stack.push(node.left);
            }
            if(node.right!=null){
                stack.push(node.right);
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

Train of thought 2: recursion of preorder traversal

public class Solution {
    public void Mirror(TreeNode root) {
        if(root == null)  return;
        if(root.left != null || root.right != null)
        {   
        //Create temporary nodes and exchange left and right nodes       
            TreeNode tempNode = null;           
            tempNode = root.left;
            root.left = root.right;
            root.right = tempNode;
            Mirror(root.left);
            Mirror(root.right);

        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

20. Print matrix clockwise

Title Description
Enter a matrix and print out each number in a clockwise order from the outside to the inside. For example, if you enter the following matrix:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
Then print out the numbers 1, 2, 3, 4, 8, 12, 16, 15, 14, 13, 9, 5, 6, 7, 11, 10

import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printMatrix(int [][] matrix) {
       ArrayList<Integer> list = new ArrayList<Integer>();
        int rows = matrix.length;
        int columns = matrix[0].length;

        if(matrix == null || columns <= 0 || rows <= 0){
            return null;
        }
        int start = 0;
        while(columns > start *2 && rows > start * 2){
            print1Circle(list,matrix,columns,rows,start);
            start++;
        }

        return list;
    }

    public void print1Circle(ArrayList<Integer> list, int[][] matrix,int columns, int rows, int start) {
        int endX = columns - 1 - start;
        int endY = rows - 1 - start;

        //Print a line from left to right
        for (int i = start; i <= endX; i++) {
            list.add(matrix[start][i]);
        }

        //Print a column from top to bottom with at least two lines
        if (start < endY){
            for (int i = start+1; i <= endY; i++) {
                list.add(matrix[i][endX]);
            }
        }

         //Print a row from right to left with at least two rows and two columns
        if (start < endY && start < endX){
            for (int i = endX - 1; i >= start; i--) {
                list.add(matrix[endY][i]);
            }
        }

         //Print a column from the bottom up, with at least three rows and two columns
        if (start < endY -1 && start < endX){
            for (int i = endY - 1; i >= start + 1; i--) {
                list.add(matrix[i][start]);
            }
        }     

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

21. Stack containing min function

Title Description
Define the data structure of the stack. In this type, implement a min function that can get the minimum elements of the stack.

import java.util.Stack;

/*Idea: use one stack of data to save data, and another auxiliary stack min to save the minimum number of data in sequence
 For example, in data, stack in turn, 5, 4, 3, 8, 10, 11, 12, 1
       Then min will be pushed in sequence, 5, 4, 3, 3, 3, 3, 3, 1
 Every time you enter the stack, if the element in the stack is smaller than or equal to the top of the stack in min, it will enter the stack, otherwise it is not as good as the stack.
*/ 
public class Solution {
    Stack data=new Stack();
    Stack min=new Stack();

    public void push(int node) {
        if(min.empty()){
            min.push(node);
        }else{
            int top=(int)min.peek();
            if(node<top){
               min.push(node);
            }else{
                min.push(top);
            }
        }
        data.push(node);
    }

    public void pop() {
        if(!(data.empty())){
            data.pop();
            min.pop();
        }
    }

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

    public int min() {
       if(min.empty()){
           return 0;
       }
       return (int)min.peek();    
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

22. Push and pop sequence of stack

Title Description
Enter two integer sequences. The first sequence represents the push order of the stack. Please judge whether the second sequence is the pop-up order of the stack. Assume that all the numbers pushed into the stack are not equal. For example, sequence 1,2,3,4,5 is the pressing sequence of a stack, sequence 4,5,3,2,1 is a pop-up sequence corresponding to the pressing sequence, but 4,3,5,1,2 cannot be the pop-up sequence of the pressing sequence.

[idea] borrowing an auxiliary stack, push sequence is successively pushed in the stack, and each time it is judged whether the top element of the stack is equal to the pop sequence. If it is equal, the stack will pop up. If it is not equal, push sequence will continue to be pushed in the stack, and finally it is judged whether the stack is empty
give an example:
Stack 1,2,3,4,5
Stack 4,5,3,2,1
First, input the auxiliary stack 1, and then input the stack top 1 ≠ 4, and continue to input the stack 2
At this time, stack top 2 ≠ 4, continue to stack 3
At this time, stack top 3 ≠ 4, continue to stack 4
At this time, stack top 4 = 4, stack exit 4, pop-up sequence is one bit backward, at this time, it is 5, and auxiliary stack is 1, 2, 3
At this time, stack top 3 ≠ 5, continue to stack 5
At this time, stack top 5 = 5, stack out 5, pop-up sequence is one bit backward, at this time, it is 3, and auxiliary stack is 1, 2, 3
....
Execute in turn, and the auxiliary stack is empty at last. If not empty, the pop-up sequence is not the pop-up sequence of the stack.

import java.util.ArrayList;
import java.util.Stack;
public class Solution {
    public boolean IsPopOrder(int [] pushA,int [] popA) {
        if(pushA.length == 0 || popA.length == 0)
            return false;
        Stack<Integer> s = new Stack<Integer>();
        //Used to identify the location of the pop-up sequence
        int popIndex = 0;
        for(int i = 0; i< pushA.length;i++){
            s.push(pushA[i]);
            //If the stack is not empty and the top element of the stack is equal to the pop-up sequence
            while(!s.empty() &&s.peek() == popA[popIndex]){
                //Out of the stack
                s.pop();
                //Pop up sequence one bit backward
                popIndex++;
            }
        }
        return s.empty();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

23. Print binary tree from top to bottom -- level traversal

Title Description
Each node of the binary tree is printed from top to bottom, and the nodes of the same layer are printed from left to right.

Idea: a queue container. Each time you print a node, add the left and right child nodes of the node

import java.util.*;
/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        if(root==null){
            return list;
        }
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            TreeNode treeNode = queue.poll();
            if (treeNode.left != null) {
                queue.offer(treeNode.left);
            }
            if (treeNode.right != null) {
                queue.offer(treeNode.right);
            }
            list.add(treeNode.val);
        }
        return list;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

24. Post order traversal sequence of binary search tree

Title Description
Input an integer array to determine whether the array is the result of the sequential traversal of a two pronged search tree. If Yes, output Yes; otherwise, output No. Suppose that any two numbers of the input array are different from each other.

public class Solution {
    public static boolean VerifySquenceOfBST(int[] sequence) {
        if(sequence.length ==0){
            return false;
        }
        return VerifySquenceOfBST1(sequence,0,sequence.length-1);
    }

    public static boolean VerifySquenceOfBST1(int[] sequence,int start,int end) {

        if(start > end)
            return true;
        int root=sequence[end];//The last node is the root node

       //The left subtree node is smaller than the root node in the binary search tree
        int i=0;
        for(;i<end;i++){
            if(sequence[i]>root){
                break;
            }
        }

        //Right subtree node is larger than root node in binary search tree
        int j=i;
        for(;j<end;j++){
            if(sequence[j]<root)
                return false;
        }
        boolean left=true;
        boolean right=true;
        if(i>start){
            left=VerifySquenceOfBST1(sequence,start,i-1);
        }
        if(i<sequence.length-1)
            right=VerifySquenceOfBST1(sequence,i,end-1);
        return (left&&right);

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

25. Path with a certain value in binary tree

Title Description
Input a binary tree and an integer, and print out all paths in which the sum of node values in the binary tree is the input integer. Path is defined as a path from the root node of the tree to the node that the leaf node passes through.

import java.util.ArrayList;
import java.util.Stack;
/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/

public class Solution {
    public ArrayList<ArrayList<Integer>> FindPath(TreeNode root, int target) {
        ArrayList<ArrayList<Integer>> pathList=new ArrayList<ArrayList<Integer>>();
        if(root==null)
            return pathList;
        Stack<Integer> stack=new Stack<Integer>();
        FindPath(root,target,stack,pathList );
        return pathList;

    }
    private void FindPath(TreeNode root, int target, Stack<Integer> path, ArrayList<ArrayList<Integer>> pathList) {
        if(root==null)
            return;
        //If it is a leaf node, judge whether the value is the target value
        if(root.left==null&&root.right==null){
            if(root.val==target){
                ArrayList<Integer> list=new ArrayList<Integer>();
                for(int i:path){
                    list.add(new Integer(i));
                }
                list.add(new Integer(root.val));
                pathList.add(list);
            }
        }
        else{//If it is not a leaf node, it will traverse its child nodes
            path.push(new Integer(root.val));
            //It is to find the path by traversing it in the previous order. If you exit to the parent node, you need to return to the target value instead of the target value- root.val
            FindPath(root.left, target-root.val, path, pathList);
            FindPath(root.right, target-root.val, path,  pathList);
            path.pop();
        }

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

26. Copy of complex linked list

Title Description
Enter a complex list of links (each node has a node value, and two pointers, one to the next node, and one special pointer to any node).

Method 1: map the original linked list with hashMap, sacrificing O (N) space for time

/*
public class RandomListNode {
    int label;
    RandomListNode next = null;
    RandomListNode random = null;

    RandomListNode(int label) {
        this.label = label;
    }
}
*/
import java.util.HashMap; 
public class Solution {

    public RandomListNode Clone(RandomListNode pHead)

    {

        if(pHead == null) return null;

        HashMap<RandomListNode, RandomListNode> map = new HashMap<RandomListNode, RandomListNode>();

        RandomListNode newHead = new RandomListNode(pHead.label);//Copy head node of linked list

        RandomListNode pre = pHead, newPre = newHead; 
        map.put(pre, newPre);

        //The first step is to save the hashMap and map and copy the original linked list node
        while(pre.next != null){ 
            newPre.next = new RandomListNode(pre.next.label); 
            pre = pre.next; 
            newPre = newPre.next; 
            map.put(pre, newPre); 
        }

        //Step 2: find the corresponding random
        pre = pHead; 
        newPre = newHead;

        while(newPre != null){ 
            newPre.random = map.get(pre.random); 
            pre = pre.next; 
            newPre = newPre.next; 
        }

        return newHead; 
    } 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

Method 2: do not borrow auxiliary space

/*
public class RandomListNode {
    int label;
    RandomListNode next = null;
    RandomListNode random = null;

    RandomListNode(int label) {
        this.label = label;
    }
}
*/
public class Solution {
    public RandomListNode Clone(RandomListNode pHead){
        if(pHead==null)
            return null;
        RandomListNode pCur = pHead;
        //Step 1: copy next as a - > b - > C turns into a - > A - > b - > b - > C - > C '
        while(pCur!=null){
            RandomListNode node = new RandomListNode(pCur.label);
            node.next = pCur.next;
            pCur.next = node;
            pCur = node.next;
        }

        //Step 2
        pCur = pHead;
        //Replication random pCur is the node of the original linked list pCur.next Is the node of the copy pcur
        while(pCur!=null){
            if(pCur.random!=null)
                pCur.next.random = pCur.random.next;
            pCur = pCur.next.next;
        }

        //Step 3
        RandomListNode head = pHead.next;//Copy head node of linked list
        RandomListNode cur = head;//Even position is copy linked list
        pCur = pHead;//Odd position is the original linked list
        //Split linked list
        while(pCur!=null){
            pCur.next = pCur.next.next;
            if(cur.next!=null)//Note that there is no next when the last replication node
                cur.next = cur.next.next;
            cur = cur.next;
            pCur = pCur.next;
        }
        return head;       
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

27. Binary search tree and double linked list

Title Description
Input a binary search tree, and transform the binary search tree into a sorted bidirectional linked list. It is required that no new node can be created, only the node pointer in the tree can be adjusted.

Method 1: recursive middle order traversal

/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;
    }
}
*/
//Direct traversal in middle order
public class Solution {
    TreeNode head = null;
    TreeNode realHead = null;//The head node of double linked list
    public TreeNode Convert(TreeNode pRootOfTree) {
        if(pRootOfTree==null) return null;
        Convert(pRootOfTree.left);
        if (head == null) {
            head = pRootOfTree;
            realHead = pRootOfTree;
        } else {
            head.right = pRootOfTree;
            pRootOfTree.left = head;
            head = pRootOfTree;
        }
        Convert(pRootOfTree.right);
        return realHead;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

Method 2:

/** non-recursive  */
import java.util.Stack;
public class Solution {
    public TreeNode Convert(TreeNode pRootOfTree) {
        if(pRootOfTree == null) return pRootOfTree;

        TreeNode list = null;
        Stack<TreeNode> s = new Stack<>();
        while(pRootOfTree != null || !s.isEmpty()){
            if(pRootOfTree != null) {
                s.push(pRootOfTree);
                pRootOfTree = pRootOfTree.right;
            } else {
                pRootOfTree = s.pop();
                if(list == null)
                    list = pRootOfTree;
                else {
                    list.left = pRootOfTree;
                    pRootOfTree.right = list;
                    list = pRootOfTree;
                }
                pRootOfTree = pRootOfTree.left;
            }
        }

        return list;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

28. String arrangement

Title Description
Enter a string and print all the permutations of the characters in the string in dictionary order. For example, the input string a B C will print out all the strings abc, a C B, BAC, B C A, cab and cba that can be arranged by the characters a, B and C. Please output the results in alphabetical order.

Extension: finding the full combination of strings

For example: a B C, the whole combination is: a,b,c,ab,ac,bc,abc

public final class PermutationCombinationHolder {

    /** 1,Full combination of array elements */
  public  static void combination(char[] chars) {
        char[] subchars = new char[chars.length]; //Array to store sub composite data
        //The problem of complete combination is the combination of one of all elements (n), plus the combination of two elements... Plus the combination of n elements
        for (int i = 0; i < chars.length; ++i) {
            final int m = i + 1;
            combination(chars, chars.length, m, subchars, m);
        }
    }

    /**
     *  n The principle is as follows:
     *  Select from back to front, select position i, and then select m-1 of the first i-1
     *  For example: 1, 2, 3, 4, 5 select three elements
     *  1) Select 5, then select 2 of the first 4, and select 2 of the first 4 is a sub problem, recursion is OK;
     *  2) If it does not contain 5, select 4 directly, then select 2 of the first 3, and select 2 of the first three is a sub problem, recursion is OK;
     *  3) If it does not include 4, select 3 directly, then select 2 of the first 2, just two
     *  Vertically, 1 and 2 and 3 are just a for cycle, with initial value of 5 and final value of m
     *  Horizontally, the problem is a recursion of m-1 among the first i-1
     */
    public static void combination(char[] chars, int n, int m, char[] subchars, int subn) {
        if (m == 0) { //exit
            for (int i = 0; i < subn; ++i) {
                System.out.print(subchars[i]);
            }
            System.out.println();
        } else {
            for (int i = n; i >= m; --i) { // Select one from back to front
                subchars[m - 1] = chars[i - 1]; // After selecting one
                combination(chars, i - 1, m - 1, subchars, subn); // Select m-1 from i-1 for recursion
            }
        }
    }
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////


    /** 2,Full array of array elements */
   public static void permutation(char[] chars) {
        permutation(chars, 0, chars.length - 1);
    }

    /** Sub array from index begin to index end in array participates in Full Permutation */
   public static void permutation(char[] chars, int begin, int end) {
        if (begin == end) { //Exit when only the last character is left
            for (int i = 0; i < chars.length; ++i) {
                System.out.print(chars[i]);
            }
            System.out.println();
        } else {
            for (int i = begin; i <= end; ++i) { //Each character in turn is fixed to the first of an array or subarray
                if (canSwap(chars, begin, i)) { //duplicate removal
                    swap(chars, begin, i); //exchange
                    permutation(chars, begin + 1, end); //Recursively finding the total arrangement of subarrays
                    swap(chars, begin, i); //reduction
                }
            }
        }
    }

    public static void swap(char[] chars, int from, int to) {
        char temp = chars[from];
        chars[from] = chars[to];
        chars[to] = temp;
    }

    //Judgment de duplication
  public static boolean canSwap(char[] chars, int begin, int end) {
        for (int i = begin; i < end; ++i) {
            if (chars[i] == chars[end]) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        final char[] chars = new char[] {'a', 'b', 'c'};
        permutation(chars);
        System.out.println("===================");
        combination(chars);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85

Method 2: DFS

 import java.util.*;

public class Solution {
    private char [] seqs;
    private Integer [] book;
    //Used for result de duplication
    private HashSet<String> result = new HashSet<String>();
    /**
     * Enter a string and print all the permutations of the characters in the string in dictionary order.
     * For example, if the input string a B C is used, the characters a,b,c will be printed out
     * All the strings abc,acb,bac,bca,cab and cba that can be arranged. Please output the results in alphabetical order.
       Enter a string that is no longer than 9 (there may be duplicate characters) and contains only uppercase and lowercase letters. "
     * @param str
     * @return
     */
    public ArrayList<String> Permutation(String str) {
        ArrayList<String> arrange = new ArrayList<String>();
        if(str == null || str.isEmpty()) return arrange;
        char[] strs = str.toCharArray();
        seqs = new char[strs.length];
        book = new Integer[strs.length];
        for (int i = 0; i < book.length; i++) {
            book[i] = 0;
        }
        dfs(strs, 0);
        arrange.addAll(result);
        Collections.sort(arrange);
        return arrange;
    }

    /**
     * Depth traversal method
     */
    private void dfs(char[] arrs, int step){
        //Go through all possible records
        if(arrs.length == step){
            String str = "";
            for (int i = 0; i < seqs.length; i++) {
                str += seqs[i];
            }
            result.add(str);
            return; //Go back to the previous step
        }
        //Traverse the entire sequence, trying every possible
        for (int i = 0; i < arrs.length; i++) {
            //Walk or not
            if(book[i] == 0){
                seqs[step] = arrs[i];
                book[i] = 1;
                //next step
                dfs(arrs, step + 1);
                //Step back after the last step
                book[i] = 0;
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

Method 3: dictionary order algorithm

 import java.util.*;

//The steps are as follows:
//1.From right to left in this sequence, find the first character whose left neighbor is smaller than the right neighbor,Record subscript is index1 ´╝îIf not found, the solution is complete.
//2.Find the first greater than from right to left in this sequence str[index1]The character of, the record subscript is index2
//3.exchange index1 and index2 Characters of, yes index1+1All subsequent characters are sorted in ascending order, and the result is str Next in dictionary order
//4. repeat1~3Until all of them are found 

public class Solution {
    public ArrayList<String> Permutation(String str) {
           ArrayList<String> res = new ArrayList<>();

            if (str != null && str.length() > 0) {
                char[] seq = str.toCharArray();
                Arrays.sort(seq); //array
                res.add(String.valueOf(seq)); //Output a solution first

                int len = seq.length;
                while (true) {
                    int p = len - 1, q;
                    //Find one back and forth seq[p - 1] < seq[p]
                    while (p >= 1 && seq[p - 1] >= seq[p]) --p;
                    if (p == 0) break; //Is already the "smallest" arrangement, exit
                    //Find the last se from pq[p]A large number
                    q = p; --p;
                    while (q < len && seq[q] > seq[p]) q++;
                    --q;
                    //Exchange values at these two locations
                    swap(seq, q, p);
                    //take p Reverse sequence after
                    reverse(seq, p + 1);
                    res.add(String.valueOf(seq));
                }
            }

            return res;
        }

        public static void reverse(char[] seq, int start) {
            int len;
            if(seq == null || (len = seq.length) <= start)
                return;
            for (int i = 0; i < ((len - start) >> 1); i++) {
                int p = start + i, q = len - 1 - i;
                if (p != q)
                    swap(seq, p, q);
            }
        }

        public static void swap(char[] cs, int i, int j) {
            char temp = cs[i];
            cs[i] = cs[j];
            cs[j] = temp;
        }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

29. Numbers in the array that appear more than half of the times

Title Description
There is a number in the array that appears more than half the length of the array. Please find this number. For example, enter an array of length 9 {1,2,3,2,2,2,5,4,2}. Since the number 2 appears five times in the array, more than half the length of the array, output 2. Output 0 if it does not exist.

Idea: the idea of O(n) is to define two variables, result and count. If the value of array[i] is equal to result in each cycle, the count will increase automatically. If not equal and count > 0, the count will decrease automatically, count==0. Re assign temp to current array[i], and count to 1.
If there is more than half of the data, the result will be returned directly, but there is no such situation in the test data, so a check is made at last to check whether the current result value has been more than half.

public class Solution {
   public int MoreThanHalfNum_Solution(int [] array) {
       if(array==null || array.length <= 0){
           return 0;
       }

       int result = array[0];
       int count = 1;
       for (int i = 1; i < array.length; i++) {
           if (array[i] == result) {
               count++;
           } else if (count > 0 ) {
               count--;
           } else if(count == 0){
               result = array[i];
               count = 1;
           }
       }
       //verification
       count=0;
       for(int i=0;i<array.length;i++){
           if(array[i]==result)
                count++;
       }
       return count > array.length/2 ? result : 0;
   }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

30. Minimum number of K

Title Description
Enter n integers to find the minimum number of K. For example, if you enter 8 numbers of 4,5,1,6,2,7,3,8, the minimum 4 numbers are 1,2,3,4,.

Train of thought 1:
The classic algorithm, the essence of fast sorting, uses the idea of fast sorting division. Each division will have a number in the final position index from array to array;

The numbers on the left side of index are smaller than the corresponding values of index, and the numbers on the right side are larger than the values pointed to by index;

Therefore, when index > k-1, it means that the K minimum number must be on the left side of index. At this time, only the left side of index needs to be divided;

When index is less than k - 1, it means that the numbers on the left side of index and index are not enough for K numbers, so it is necessary to continue to divide the right side of K;

//The advantage of this method is that the time complexity is less than O(n), and the disadvantage is that the input array needs to be modified.
import java.util.ArrayList;
public class Solution {
    public ArrayList GetLeastNumbers_Solution(int [] input, int k) {
        ArrayList aList = new ArrayList();
        if(input.length == 0 || k > input.length || k <= 0)
            return aList;
        int low = 0;
        int high = input.length-1;
        int index = Partition(input,k,low,high);
        while(index != k-1){
            if (index > k-1) {
                high = index-1;
                index = Partition(input,k,low,high);
            }else{
                low = index+1;
                index = Partition(input,k,low,high);
            }
        }
        for (int i = 0; i < k; i++)
            aList.add(input[i]);
        return aList;
    }

    //For quick sorting segments, those smaller than a certain number are placed on the left, and those larger than a certain number are moved to the right
    public int Partition(int[] input,int k,int low,int high){
        int pivotkey = input[k-1];
        swap(input,k-1,low);
        while(low < high){
            while(low < high && input[high] >= pivotkey)
                high--;
            swap(input,low,high);
            while(low < high && input[low] <= pivotkey)
                low++;
            swap(input,low,high);
        }
        return low;
    }


    private void swap(int[] input, int low, int high) {
        int temp = input[high];
        input[high] = input[low];
        input[low] = temp;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

Train of thought 2

  • You can first create a data container with the size of K to store the smallest K numbers, read them from one of the n integers you enter into the container, and if the number in the container is less than k, return to null directly according to the requirements of the topic;

  • If there are k numbers in the container, and there are still values in the array that have not been added, then you cannot insert them directly, but you need to replace the values in the container. Insert as follows:

  • 1. First find the maximum value in the container;
  • 2. Compare the value to be queried with the maximum value. If the value to be queried is greater than the maximum value in the container, discard the value directly. If the value to be queried is less than the minimum value in the container, replace the maximum value in the container with the value to be queried;
  • 3. Repeat the above steps, and the last part of the container is the minimum k number of the whole array.

-For the implementation of this container, we can use the data structure of the maximum heap. In the maximum heap, the value of the root node is greater than that of any node in its subtree. The TreeSet class in Java implements the function of red black tree. Its bottom layer is realized by TreeMap. The data in TreeSet will be automatically arranged in ascending order (in natural order) according to the inserted data. So we put the data directly into TreeSet, and the array will be sorted automatically.

public static ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {
        ArrayList<Integer> leastNum = new ArrayList<Integer>();
        if (input == null || input.length < 1 || k < 1 || k > input.length)
            return leastNum;
        TreeSet<Integer> kSet = new TreeSet<Integer>();
        for (int i = 0; i < input.length; i++) {
            if (kSet.size() < k) {
                kSet.add(input[i]);
            } else {
                if (input[i] < kSet.last()) {
                    kSet.remove(kSet.last());
                    kSet.add(input[i]);
                }
            }
        }
        Iterator<Integer> it = kSet.iterator();
        while (it.hasNext()) {
            leastNum.add(it.next());
        }

        return leastNum;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

31. The maximum sum of successive subarrays

Title Description:
Enter an integer array with positive and negative numbers. One or more consecutive numbers in the array form a subarray to find the maximum value of all subarrays. The time complexity is required to be O(N)

Train of thought 1:

/*
Algorithm time complexity O (n)
Use total to record cumulative value, maxSum to record and maximum
 Based on the idea: for A number A, if the left cumulative number of A is not negative, then add A to make the value not less than A, and the cumulative value is considered to be
          The overall sum is contributive. If the previous cumulative value is negative, it is considered harmful to the sum, and total records the current value.
At this time, if the sum is greater than maxSum, record it with maxSum
*/
public class Solution {
    public int FindGreatestSumOfSubArray(int[] array) {
        if(array.length==0)
            return 0;
        else{
            int total=array[0],maxSum=array[0];
            for(int i=1;i<array.length;i++){
                if(total>=0)
                    total+=array[i];
                else
                    total=array[i];
                if(total>maxSum)
                    maxSum=total;
            }
            return maxSum;
        }

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

Train of thought 2: dynamic planning (quite important)

public class Solution {
    public int FindGreatestSumOfSubArray(int[] array) {
        //Dynamic programming, mainly to find the state transfer equation
        //Let f(j) be the maximum sum from s[0] to s[j]
        //f(j) = max(s[j], f[j-1]+s[j])
        if(array.length == 0)
            return 0;
        int result = Integer_MinValue;
        int sum = 0;
        for(int i = 0; i < array.length; ++i)
        {
            sum = max(array[i], sum + array[i]);
            result = max(result, sum);
        }
        return result;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

32. Number of occurrences of 1 in an integer (number of occurrences of 1 in an integer from 1 to n)

Title Description
For example, the number of occurrences of 1 in an integer with n=13, and the number of occurrences of 1 in 1-13 is 1, 10, 11, 12, 13, so there are 6 occurrences in total

Ideas:
1, Number of 1

The rules given in the beauty of programming:
1. If the number on the i-th digit (right to left, starting from 1) is 0, the number of times that the i-th digit may appear 1 is determined by the higher order (if there is no high order, the higher order is 0), equal to the higher order digit * the weight of the current digit 10^(i-1).

2. If the number on the i-th digit is 1, the number of times that 1 may appear on the i-th digit is not only affected by the higher order, but also affected by the lower order (if there is no lower order, the lower order is regarded as 0), equal to the higher order digit * the weight of the current digit 10^(i-1) + (the lower order digit + 1).

3. If the number on the i-th digit is greater than 1, the number of times that 1 may appear on the i-th digit is only determined by the higher order (if there is no high order, the high order is regarded as 0), equal to (higher order digit + 1) × the weight of the current digit 10^(i-1).

2, Number of X
Here X ∈ [1,9], because X=0 does not conform to the following rules, it needs to be calculated separately.

First of all, we should know the following laws:
From 1 to 10, any X appears once in their single digits.
From 1 to 100, any X appears 10 times in their tens.
From 1 to 1000, any X appears 100 times in their hundreds.

And so on, from 1 to 10^ i, in their second left digit (the first right digit), any X appears 10^ i-1 times.

This rule is easy to verify, so I will not explain it here.
Next, take n=2593,X=5 as an example to explain how to get the mathematical formula. From 1 to 2593, the number 5 appeared 813 times in total, of which 259 times appeared in bits, 260 times in tens, 294 times in hundreds and 0 times in thousands.

Now analyze the data in turn,
The first is a bit. From 1 to 2590, there are 259 10s, so any x occurs 259 times. The last three remaining numbers, 2591, 2592 and 2593, will not contain any 5 because their largest digit number, 3 < X. (it can also be seen that if 3 < x, the number of times that x may appear on a single digit is only determined by the higher digit, which is equal to the higher digit (259) * 10 ^ (1-1) = 259).

Then there are ten. From 1 to 2500, there are 25 100, so any X appears 25 × 10 = 250 times. The remaining numbers are from 2501 to 2593, and their maximum ten digits are 9 > X, so they will contain all 10 5's. The final total is 250 + 10 = 260. (it can also be seen that, if 9 > X, the number of times that X may appear on the ten digit is only determined by the higher digit, which is equal to the higher digit (25 + 1) × 10 ^ (2-1) = 260).

Next is the hundred. From 1 to 2000, there are two 1000, so any x appears 2 × 100 = 200 times. The remaining numbers are from 2001 to 2593, and their largest 100 digit number is 5==X. at this time, the situation is slightly complicated. Their 100 digit number must contain 5, but not all 100. If you list a number with five hundred digits, it is from 2500 to 2593. The number of digits is related to hundred digits and ten digits, which is 93 + 1 = 94. The final total is 200 + 94 = 294. (it can also be seen that if 5==X, the number of times that x may appear on the hundreds is not only affected by the higher order, but also by the lower order, equal to the higher order number (2 * 10 ^ (3-1) + (93 + 1) = 294).

The last is the thousand. Now there is no higher order, so look directly at the largest number 2 < X, so it will not contain any 5. (it can also be seen that if 2 < X, the number of times that X may appear on the kilobit is only determined by the higher digit, which is equal to the higher digit (0) * 10 ^ (4-1) = 0).
So far, the number of occurrences of all the numbers 5 has been calculated.

To sum up the above algorithms, we can see that when calculating the number of X contained in the i-th bit of the right number:

  • 1. Take the number to the left of the i-th digit (high position), multiply by 10 ^(i − 1), and get the basic value a.
  • 2. Take the i-th digit and calculate the correction value:
    • 1. If it is greater than X, the result is a+ 10 ^(i − 1).
    • 2. If less than X, the result is a.
    • 3. If it is equal to X, take the right (low) number of the i-th digit, set it to b, and the final result is a+b+1.

The corresponding code is very simple and efficient, and the time complexity is only O (log 10N).

public class Solution {
    public int NumberOf1Between1AndN_Solution(int n) {
        //When x=1
        return NumberOfXBetween1AndN_Solution1(n,1);       
    }

 /**
 * @param n
 * @param x [1,9]
 * @return (Number of occurrences of x in integers from 1 to n)
 */
    public int NumberOfXBetween1AndN_Solution1(int n,int x) {
        if(n<0||x<1||x>9)
            return 0;
        int high,low,curr,tmp,i = 1;
        high = n;
        int total = 0;
        while(high!=0){
            high = n/(int)Math.pow(10, i);// Get the high bit of i
            tmp = n%(int)Math.pow(10, i);
            curr = tmp/(int)Math.pow(10, i-1);// Get i
            low = tmp%(int)Math.pow(10, i-1);// Get the low bit of i
            if(curr==x){
                total+= high*(int)Math.pow(10, i-1)+low+1;
            }else if(curr<x){
                total+=high*(int)Math.pow(10, i-1);
            }else{
                total+=(high+1)*(int)Math.pow(10, i-1);
            }
            i++;
        }
        return total;       
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

33. Arrange the array into the smallest number

Title Description:
Input a positive integer array, put all the numbers in the array together to form a number, and print the smallest of all the numbers that can be spliced. For example, if the input array {3, 32321}, the minimum number that can be printed out is 321323.

package cn.zhuang.offer;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;

public class Main {

/* Solutions:
 * Considering the problem of large numbers, first convert the integer array into a String array, then sort the String array, and finally splice the sorted String array. The key is to make the sorting rules.
 * The sorting rules are as follows:
 * If a b > b a, a > b,
 * A < B if AB < Ba,
 * If a B = B a, a = b;
 * Explanation:
 * For example, "3" < "31" but "331" > 313 ", so we need to splice them for comparison
 */
    public static String PrintMinNumber(int [] numbers) {
        if(numbers == null || numbers.length == 0) return "";
        int len = numbers.length;
        String[] str = new String[len];
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < len; i++){
            str[i] = String.valueOf(numbers[i]);
        }

        //This is more important. New sorting rules, such as ~ c1.compareTo(c2) if the maximum value is taken
        Arrays.sort(str,new Comparator<String>(){
            @Override
            public int compare(String s1, String s2) {
                String c1 = s1 + s2;
                String c2 = s2 + s1;
                return c1.compareTo(c2);
            }
        });
        for(int i = 0; i < len; i++){
            sb.append(str[i]);
        }
        return sb.toString();
    }

    public static void main(String[] args){
        int[] a = {3,32,421};
        System.out.println(PrintMinNumber(a));
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

The compareto method in java returns the difference between the asc codes of the two strings before and after the comparison. See the following set of codes
String a="a",b="b";
System.out.println(a.compareto.b);
Then output - 1;
If a = a, b = a, output 0;
If a = b, b = a, output 1;

Single character comparison, if the string is longer??
If a = a b, b = b, output - 1;
If a = abcdef, b = b, output - 1;
That is to say, if the initials of two strings are different, the method returns the difference of the asc code of the initials;

What if the initials are the same??
If a = a b, b = a, output 1;
If a = abcdef, b = a output 5;
If a = abcdef, b = abc output 3;
If a= "abcdef", b= "ace" output -1;
That is to say, if the first character of the two strings involved in the comparison is the same, the next character will be compared until there is a difference, and the asc code difference of the different characters will be returned. If the two strings are not the same length, and the characters that can participate in the comparison are exactly the same, the length difference of the two strings will be returned

34. Ugly number

Title Description:
A number that contains only factors 2, 3, and 5 is called an Ugly Number. For example, 6 and 8 are ugly numbers, but 14 is not, because it contains factor 7. We used to think of 1 as the first Ugly Number. Find the nth Ugly Number from small to large.

Idea 1: the simplest way is to determine whether a number is ugly by dividing it by 2, 3 and 5. Then, from 1, judge whether each number is ugly in turn, and record the number of ugly numbers. When the number is a given value, it is the nth ugly number required. The time complexity of this method is O (k), where k is the nth ugly number For example, if the size of the 1500th ugly number is 859963392, you need to judge 859963392 times, which is very inefficient.

public boolean IsUgly(int number)
{
    while(number % 2 == 0)
        number /= 2;
    while(number % 3 == 0)
        number /= 3;
    while(number % 5 == 0)
        number /= 5;

    return (number == 1) ? true : false;
}

public int GetUglyNumber(int index)
{
    if(index <= 0)
        return 0;

    int number = 0;
    int uglyFound = 0;
    while(uglyFound < index)
    {
        ++number;

        if(IsUgly(number))
        {
            ++uglyFound;
        }
    }

    return number;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

Idea better 2: the intuitive optimization measure is to see if we can reduce the time complexity to O(n), that is, we can only spend time on ugly numbers, not on non ugly numbers. The idea of sword finger offer is very good. The time complexity of O(n) is obtained by using O(n) auxiliary space. The core idea is: every ugly number must be obtained by the product of a previous ugly number and 2, 3 or 5. In this way, the next ugly number is multiplied by 2, 3, 5 by the previous ugly number respectively. Find out the minimum value of these three and the value greater than the current maximum ugly number, which is the next required ugly number.

import java.util.*;
public class Solution
{
    public int GetUglyNumber_Solution(int n)
    {
        if(n==0)return 0;
        ArrayList<Integer> res=new ArrayList<Integer>();
        res.add(1);
        int i2=0,i3=0,i5=0;
        while(res.size()<n)
        {
            int m2=res.get(i2)*2;
            int m3=res.get(i3)*3;
            int m5=res.get(i5)*5;
            int min=Math.min(m2,Math.min(m3,m5));
            res.add(min);
            if(min==m2)i2++;
            if(min==m3)i3++;
            if(min==m5)i5++;
        }
        return res.get(res.size()-1);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

35. The first character that only appears once

Description: find the position of the first once occurrence character in a string (1 < = string length < = 10000, all composed of letters). If it is an empty string, return - 1. Position index starts from 0, such as "abaccdrff", then output "b"

First, array method:

public class Solution {
   public int FirstNotRepeatingChar(String str) {
        if (str.length() == 0) {
            return  -1;
        }
        char c = 'A';
        if(str.charAt(0) >= 'a'){
            c = 'a';
        }
        int[] counts = new int[26];
        for (int i = 0; i < str.length(); i++) {
            counts[str.charAt(i) - c]++;
        }
        for (int i = 0; i < str.length(); i++) {
            if (counts[str.charAt(i) - c] == 1){
                return i;
            }
        }
        return -1;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

Second, the HashMap method:

import java.util.LinkedHashMap;
// use linkedhashmap to keep the order
public class Solution {
    public int FirstNotRepeatingChar(String str) {
        LinkedHashMap <Character, Integer> map = new LinkedHashMap<Character, Integer>();
        for(int i=0;i<str.length();i++){
            if(map.containsKey(str.charAt(i))){
                int time = map.get(str.charAt(i));
                map.put(str.charAt(i), ++time);
            }
            else {
                map.put(str.charAt(i), 1);
            }
        }
        int pos = -1;  
        int i=0;
        for(;i<str.length();i++){
            char c = str.charAt(i);
            if (map.get(c) == 1) {
                return i;
            }
        }
        return pos;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

36. Reverse pairs in array

Title Description:
Two numbers in an array, if the first number is greater than the latter, then the two numbers form an inverse pair. Enter an array to find the total number of reverse pairs in the array.
{7, 5, 6, 4}, 76, 75, 74, 64, 65, five in all

Ideas:

public class Solution {
     private  int reversePair = 0;
    public int InversePairs(int [] array) {
        if(array==null)
            return 0;
        int len = array.length;
        if(len==0)
            return 0;
        sort(array,0,len-1);
        return reversePair;
    }

    private void sort(int[]arr,int start,int end){
        if(start<end){
            int mid = start+(end-start)/2;
            sort(arr,start,mid);
            sort(arr,mid+1,end);
            merger(arr,start,mid,mid+1,end);
        }
    }

    private void merger(int[] arr, int start1, int end1, int start2, int end2) {
        int len= end2-start1+1;
        int[] anx = new int[len];
        int k = end2-start1+1;

        int i = end1;
        int j= end2;
        while(i>=start1&j>=start2){
            if(arr[i]>arr[j]){
                anx[--k]=arr[i];
                i--;
                reversePair = reversePair+(j-start2+1);
            }
            else{
                anx[--k]=arr[j];
                j--;
            }
        }
        for(;i>=start1;i--)
            anx[--k]=arr[i];
        for(;j>=start2;j--)
            anx[--k]=arr[j];

        for(int m=0;m<len;m++)
            arr[start1++]=anx[m];

    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

37. The first common intersection of two linked lists

/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
       if (pHead1 == null||pHead2 == null) {
            return null;
        }
        int count1 = 0;
        ListNode p1 = pHead1;
        while (p1!=null){
            p1 = p1.next;
            count1++;
        }
        int count2 = 0;
        ListNode p2 = pHead2;
        while (p2!=null){
            p2 = p2.next;
            count2++;
        }
        int flag = count1 - count2;
        if (flag > 0){
            while (flag>0){
                pHead1 = pHead1.next;
                flag --;
            }
        while (pHead1!=pHead2){
            pHead1 = pHead1.next;
            pHead2 = pHead2.next;
        }
        return pHead1;
    }
        if (flag <= 0){
            while (flag<0){
                pHead2 = pHead2.next;
                flag ++;
            }
            while (pHead1 != pHead2){
                pHead2 = pHead2.next;
                pHead1 = pHead1.next;
            }
            return pHead1;
        }
        return null;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52

38. The number of times the number appears in the sorting array

Idea: focus on the condition of ordered array. Use dichotomy search method to find the first and the last respectively, so that the best and worst complexity is O (lgN)

public class Solution {
    public int GetNumberOfK(int [] array , int k) {
      int num = 0;
        if (array != null && array.length > 0) {
            int firstKIndex = getFirstK(array, k, 0, array.length - 1);
            int lastKIndex = getLastK(array, k, 0, array.length - 1);
            if (firstKIndex > -1 && lastKIndex > -1)
                num = lastKIndex - firstKIndex + 1;
        }
        return num;
    }

    /*
    * Find the subscript of the first number that appears
    */
    public  int getFirstK(int[] array, int k, int start, int end) {
        if (start > end)
            return -1;
        int middleIndex = start + (end - start) / 2;
        int middleData = array[middleIndex];
        if (middleData == k) {
        //Judge whether the first k is the first K. if the former is not equal to K, it is the first K
            if (middleIndex > 0 && array[middleIndex - 1] != k || middleIndex == 0) {
                return middleIndex;
            } else
                end = middleIndex - 1;
        } else if (middleData > k) {
            end = middleIndex - 1;
        } else
            start = middleIndex + 1;
        return getFirstK(array, k, start, end);
    }

     /*
    * Find the subscript of the last number that appears
    */
    public  int getLastK(int array[], int k, int start, int end) {
        if (start > end) {
            return -1;
        }
        int middleIndex = (start + end) / 2;
        int middleData = array[middleIndex];
        if (middleData == k) {
         //Judge whether the last K is not equal to K, which is the last K
            if (middleIndex < array.length - 1 && array[middleIndex + 1] != k || middleIndex == array.length - 1)
                return middleIndex;
            else
                start = middleIndex + 1;
        } else if (middleData < k) {
            start = middleIndex + 1;
        } else
            end = middleIndex - 1;
        return getLastK(array, k, start, end);

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

39. Depth of binary tree

Title Description:
Enter a binary tree to find the depth of the tree. The nodes (including root and leaf nodes) that pass from root node to leaf node form a path of the tree. The longest path length is the depth of the tree.

Idea: recursion, from the root node of the next layer to the root node of the previous layer, add 1 to the depth, judge the maximum value of the left and right subtrees, and then + 1

/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;
    public TreeNode(int val) {
        this.val = val;
    }
};*/
public class Solution {
     public int getHeight(TreeNode root) {
        if (root == null)
            return 0;
        return max(getHeight(root.left), getHeight(root.right)) + 1;
    }

    private int max(int a, int b) {
        return (a > b) ? a : b;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

Extended question: judge binary tree balance

Description: if the depth difference between the left and right subtrees of any node in a binary tree does not exceed 1, then it is a balanced binary tree.

The first idea: simple, but inefficient, because it will repeatedly traverse the child nodes

public class Solution {
   public boolean IsBalanced(TreeNode root) {
        if (root == null)
            return true;

        if (Math.abs(getHeight(root.left) - getHeight(root.right)) > 1)
            return false;


        return IsBalanced(root.left) && IsBalanced(root.right);

    }

    public int getHeight(TreeNode root) {
        if (root == null)
            return 0;
        return max(getHeight(root.left), getHeight(root.right)) + 1;
    }

    private int max(int a, int b) {
        return (a > b) ? a : b;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

The second Better idea: judge from the bottom up, so as to record the depth of the next layer

public class Solution {
  pu

Topics: Java less Programming