Java面试常见算法--持续更新

1、树的层次遍历

 // 二叉树的层序遍历
    public List<List<Integer>> levelOrder(TreeNode root) {
        // 存储结果的数组
        List<List<Integer>> res = new ArrayList<>();
        if(root == null){
            return res;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()){
            List<Integer> level = new ArrayList<>();
            int size = queue.size();
            for(int i=0; i<size; i++){
                TreeNode node = queue.poll();
                level.add(node.val);
                if(node.left != null) queue.offer(node.left);
                if(node.right != null) queue.offer(node.right);
            }
            res.add(level);
        }
        return res;
    }

2.求二叉树的最大深度

 //最大深度
    public int maxDepth(TreeNode root) {
        int maxD = 0;
        if(root == null){
            return maxD;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()){
            int size = queue.size();
            for(int i=0; i<size; i++){
                TreeNode treeNode = queue.poll();
                if(treeNode.left != null) queue.offer(treeNode.left);
                if(treeNode.right != null) queue.offer(treeNode.right);
            }
            maxD++; // 增加深度
        }
        return maxD;
    }

2、N*N旋转

3、二叉树三种遍历

3.1前序遍历

//前序遍历
void preOrderTraversal(TreeNode root) {
    if (root == null) {
        return;
    }
      System.out.print(root.val + " ");
        preOrderTraversal(root.left);
        preOrderTraversal(root.right);
}
//非递归的前序遍历
void preOrderTraversalNor(TreeNode root) {
    if (root == null) {
        return;
    }
    Stack<TreeNode> stack = new Stack<>();
    TreeNode cur = root;
    while (cur != null || !stack.empty()) {
        while (cur != null) {
            stack.push(cur);
            System.out.print(cur.val + " ");
            cur = cur.left;
        }
        TreeNode top = stack.pop();
        cur = top.right;
    }
}

3.2中序遍历

//中序遍历
void inOrderTraversal(TreeNode root) {
    if (root == null) {
        return;
    } else {
        inOrderTraversal(root.left);
        System.out.print(root.val + " ");
        inOrderTraversal(root.right);
    }
}
//非递归的中序遍历
void inOrderTraversalNor(TreeNode root) {
    if (root == null) {
        return;
    }
    Stack<TreeNode> stack = new Stack<>();
    TreeNode cur = root;
    while (cur != null || !stack.empty()) {
        while (cur != null) {
            stack.push(cur);
            cur = cur.left;
        }
        TreeNode top = stack.pop();
        System.out.print(top.val + " ");
        cur = top.right;
    }
}

3.3后序遍历

//后序遍历
void poseOrderTraversal(TreeNode root) {
    if (root == null) {
        return;
    } else {
        poseOrderTraversal(root.left);
        poseOrderTraversal(root.right);
        System.out.print(root.val + " ");
    }
}
//非递归的后序遍历
void poseOrderTraversalNor(TreeNode root) {
    if (root == null) {
        return;
    }
    Stack<TreeNode> stack = new Stack<>();
    TreeNode pre = null;
    TreeNode cur = root;
    while (cur != null || !stack.empty()) {
        while (cur != null) {
            stack.push(cur);
            cur = cur.left;
        }
        cur = stack.peek();
        if (cur.right == null||pre==cur.right) {
            TreeNode top = stack.pop();
            System.out.print(top.val+ " ");
            pre=cur;
            cur=null;
        } else {
            cur=cur.right;
        }
    }
}

4.层次遍历

void levelOderTraversal(TreeNode root) {
    Queue<TreeNode> q1 = new LinkedList<>();
    if (root == null) {
        return;
    }
    q1.offer(root);
    while (!q1.isEmpty()) {
        TreeNode top = q1.poll();
        System.out.print(top.val + " ");
        if (top.left != null) {
            q1.offer(top.left);
        }
        if (top.right != null) {
            q1.offer(top.right);
        }
    }
    System.out.println();
}

5、堆排

  //编写一个堆排序的方法
    public static void heapSort(int[] arr) {
        int length = arr.length - 1;
        int temp = 0;
        //利用循环 排成大顶堆 (叶子结点 小于父节点 满足a[i]>a[i*2+1]&&a[i]>a[i*2+2]条件 )
        for (int i = arr.length / 2 - 1; i >= 0; i--) {
            heapSort(arr, i, length);
        }

        for (; length > 0; length--) {
            temp = arr[0];
            arr[0] = arr[length];
            arr[length] = temp;
            heapSort(arr, 0, length);
        }
    }

    /**
     * 完成以i对应的非叶子节点的树  调整成大堆顶
     *
     * @param arr    待调整的数组
     * @param i      表示非叶子结点在数组中的索引
     * @param length 表示多少个元素进行调整
     */
    public static void heapSort(int[] arr, int i, int length) {
        int temp = arr[i];
        for (int k = 2 * i + 1; k <length; k = k * 2 + 1) {
            if (k + 1 < length && arr[k] < arr[k + 1]) {
                k++;
            }
            if (arr[i] < arr[k]) {
                arr[i] = arr[k];
                i = k;
            } else {
                break;
            }
        }
        arr[i] = temp;
    }

6、快排

    //快排实现方法
    public static void quickRow(int[] array,int low,int high) {
        int i,j,pivot;
        //结束条件
        if(low >= high) {
            return;
        }
        i = low;
        j = high;
        //选择的节点,这里选择的数组的第一数作为节点
        pivot = array[low];
        while(i<j) {
            //从右往左找比节点小的数,循环结束要么找到了,要么i=j
            while(array[j] >= pivot && i<j) {
                j--;
            }
            //从左往右找比节点大的数,循环结束要么找到了,要么i=j
            while(array[i] <= pivot && i<j) {
                i++;
            }
            //如果i!=j说明都找到了,就交换这两个数
            if(i<j) {
                int temp = array[i];
                array[i] = array[j];
                array[j] = temp;
            }
        }
        //i==j一轮循环结束,交换节点的数和相遇点的数
        array[low] = array[i];
        array[i] = pivot;
        //数组“分两半”,再重复上面的操作
        quickRow(array,low,i-1);
        quickRow(array,i+1,high);
    }

7、冒泡排序

int[] arr = {1,5,3,4,7,8,9,6,2,0};
  for(int i = 0; i < arr.length-1; i++)
    {
     //外循环是控制排序的次数N-1, 每次循环结束确定一个最大值
        for(int j = 0; j < arr.length - 1 - i; j++) // 内循环是比较的次数N-i
        {
            if(arr[j] > arr[j+1]){
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }

7.1直接插入排序

  public void insertSort(int[] array){
        for(int i=1;i<array.length;i++)//第0位独自作为有序数列,从第1位开始向后遍历
        {
            if(array[i]<array[i-1])//0~i-1位为有序,若第i位小于i-1位,继续寻位并插入,否则认为0~i位也是有序的,忽略此次循环,相当于continue
            {
                int temp=array[i];//保存第i位的值
                int j = i - 1;
                while(j>=0 && temp<array[j])//从第i-1位向前遍历并移位,直至找到小于第i位值停止
                {
                    array[j+1]=array[j];
                    j--;
                }
                array[j+1]=temp;//插入第i位的值
            }
        } 
    }

8.进制转换
 

    public fun converse(num:Int, radix:Int ) {
        var sb =  StringBuffer();

        var temp=num
        while (temp != 0) {
            sb.append(temp % radix);
            temp /= radix;
        }

        System.out.println(sb.reverse().toString());
    }

9、反转连接

public ListNode reverseList(ListNode head) {
      ListNode prev = null; //表示当前节点的前一个节点,初始值为null
      ListNode temp = head; //表示当前节点,初始值为head
      ListNode next; //表示当前节点的下一个节点
      while(temp != null){
          //先提前保存当前节点的下一个节点
           next = temp.next;
          //将当前节点的next指针指向当前节点的前一个节点
          temp.next = prev;
          //更新prev,即将temp赋值给prev
          prev = temp;
          //更新temp,即将next赋值给temp
          temp = next;
      }
      return prev; 
}

10、汉诺斯牌移动次数


    static int count=0;//用于计数
    public static void main(String[] args) {

        f(5);
        System.out.println(count);
    }
    public static void f(int n) {
        if(n==1) {//出口,只剩一个圆盘时只需要再移动一步,然后return整个函数
            count++;
            return;
        }
        f(n-1);//把n-1个盘子移动到辅助柱
        count++;//把最下面最大的盘子移动到C柱,因为只有一步所以,步骤++
        f(n-1);
    }
    public  static int getWalkNum2(int n) {
        if (n <= 2) {
            return n;
        }
        int first = 1, second = 2;
        int third = 0;
        for (int i = 3; i <= n; i++) {
            third = first + second;
            first = second;//计算完third值之后将second值再赋值给first
            second = third;//计算完third值之后将third值再赋值给second,方便下一轮计算
        }
        return third;
    }

10、有n步台阶,一次只能上1步或2步,共有多少种走法

    public static int getWalkNum(int n) {
        if (n <= 2) {
            return n;
        }
        return getWalkNum(n - 1)+ getWalkNum(n - 2);
    }

后面将持续更新。。。。。。。。。。。。。。。。。。。。。。。。。。。

猜你喜欢

转载自blog.csdn.net/qq36246172/article/details/130687759