面试中可能遇见的算法题

1. 快速排序

import java.util.Arrays;

/**
 * @Date: 2019/2/25 13:37
 */
public class Main {

    public static void main(String[] args) {
        int[] arr = {5, 4, 3, 2, 1, 10, 11, 15, 14, 12};
        quickSort(arr, 0, arr.length - 1);
        System.out.println(Arrays.toString(arr));
    }

    public static void quickSort(int[] data, int left, int right) {
        int start = left;
        int end = right;

        if (start > end) {
            return;
        }

        int key = data[left];

        while (end > start) {
            //从后往前找到小于key的数
            while (end > start && data[end] >= key) {
                end--;
            }
            //从前往后找到大于key的数
            while (end > start && data[start] <= key) {
                start++;
            }
            if (start < end) {
                swap(data, start, end);
            }
        }
        key = data[start];
        swap(data, left, start);//交换key和data[start]
        quickSort(data, left, start - 1);//对左边进行递归
        quickSort(data, start + 1, right);//对右边进行递归
    }

    private static void swap(int[] data, int i, int j) {
        int temp = data[i];
        data[i] = data[j];
        data[j] = temp;
    }
}

2. 全排列

import java.util.ArrayList;
import java.util.List;

/**
 * 全排列的思路是:每次交换前面第一个字符
 * 然后进行递归
 * @Date: 2019/3/4 17:33
 */
public class Solution {

    List<List<Integer>> result = new ArrayList<List<Integer>>();

    public List<List<Integer>> permute(int[] nums) {
        fullSort(nums, 0, nums.length - 1);
        return result;
    }

    /**
     * 全排列
     * @param nums  传进来的参数
     * @param start
     * @param end
     */
    public void fullSort(int[] nums, int start, int end) {
        if (start == end) {
            List<Integer> list = new ArrayList<Integer>();
            for (int num : nums) {
                list.add(num);
            }
            result.add(list);
            return;
        }
        for (int i = start; i <= end; i++) {
            swap(nums, i, start);
            fullSort(nums, start + 1, end);
            swap(nums, i, start);
        }
    }

    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }


    private void sort(int[] nums,int start,int end){
        if (start==end){
            System.out.println();
        }
    }
}

3. 堆排序

import java.util.Arrays;

/**
 * @Date: 2019/2/27 11:12
 */
public class Main {

    public static void main(String[] args) {
        int[] arr={1,2,5,4,7,6,10,56,20,34,23,9};
        heapSort(arr);
        System.out.println(Arrays.toString(arr));
    }

    public static void heapSort(int[] arr){
        int n=arr.length-1;
        for (int i=(n-1)/2;i>=0;i--){
            //构造大根堆,从下往上构造
            //i为最后一个根节点,n为数组最后一个元素的下标
            heapBuild(arr,i,n);
        }
        for (int i = n; i >0 ; i--) {
            //把最大的数,也就是顶放到最后
            //i每次减一,因为要放的位置每次都不是固定的
            swap(arr,i);
            heapBuild(arr,0,i-1);
        }
    }

    /**
     * 构造大根堆函数
     * @param arr
     * @param parent  父节点
     * @param length 数组最后一个元素的下标
     */
    private static void heapBuild(int[] arr, int parent, int length) {
        //定义临时变量存储父节点中的数据,防止被覆盖
        int temp=arr[parent];
        //2*parent+1为其左孩子节点
        for (int i = parent*2+1; i <=length; i=i*2+1) {
            //如果左孩子小于右孩子,就让i指向右孩子
            if(i<length&&arr[i]<arr[i+1]){
                i++;
            }
            //如果父节点大于或者等于较大的孩子,那就退出循环
            if(temp>=arr[i]){
                break;
            }
            //如果父节点大于或者等较大的孩子,那就把孩子节点放到父节点上
            arr[parent]=arr[i];
            //把孩子节点的下标赋值给parent
            //让其继续循环以保证大根堆的正确构造
            parent=i;
        }
        //将刚刚的父节点中的数据赋值给新位置
        arr[parent]=temp;
    }


    private static void swap(int[] arr,int i){
        int temp=arr[0];
        arr[0]=arr[i];
        arr[i]=temp;
    }
}

4. 二叉搜索树转换为双向链表

/**
 * 采用中序遍历
 * @Date: 2019/3/15 13:49
 */
public class Solution {

    private TreeNode head=null;
    private TreeNode realHead=null;

    public TreeNode Convert(TreeNode pRootOfTree) {
        inorder(pRootOfTree);
        return realHead;
    }

    public void inorder(TreeNode p){
        if (p==null){
            return;
        }
        inorder(p.left);
        if (head==null){
            head=p;
            realHead=p;
        }else{
            head.right=p;
            p.left=head;
            head=p;
        }
        inorder(p.right);
    }

}

class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

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

    }

}

5. 非递归前序、中序遍历二叉树

import org.junit.Test;

import java.util.Stack;

/**
 * @Author: Dunfu Peng
 * @Date: 2019/3/2 10:38
 */
public class BinaryTree {

    private TreeNode root=null;
    
    public void visited(TreeNode subTree){
        subTree.isVisted=true;
        System.out.println("key:"+subTree.key+"--name:"+subTree.data);;
    }

    /**
     * 非递归前序遍历
     * @param p
     */
    public void nonRecPreOrder(TreeNode p){
        Stack<TreeNode> stack=new Stack<>();
        TreeNode node=p;
        while (node!=null||stack.size()>0){
            while(node!=null){
                visited(node);
                stack.push(node);
                node=node.leftChild;
            }
            if (stack.size()>0){
                node=stack.pop();
                node=node.rightChild;
            }
        }
    }

    /**
     * 非递归中序遍历
     * @param p
     */
    public void nonRecInOrder(TreeNode p){
        Stack<TreeNode> stack=new Stack<>();
        TreeNode node=p;
        while(node!=null||stack.size()>0){

            while(node!=null){
                stack.push(node);
                node=node.leftChild;
            }
            if (stack.size()>0){
                node=stack.pop();
                visited(node);
                node=node.rightChild;
            }
        }
    }

    /**
     * 非递归后序遍历
     * @param p
     */
    public void nonRecPostOrder(TreeNode p){
        Stack<TreeNode> stack=new Stack<>();
        TreeNode node=p;
        while (p!=null){
            //左子树入栈
            while (p.leftChild!=null){
                stack.push(p);
                p=p.leftChild;
            }
            //当前节点无右子树或者右子树已经输出
            while (p!=null&&(p.rightChild==null||p.rightChild==node)){
                visited(p);
                //记录上一个已输出节点
                node=p;
                if (stack.empty()){
                    return;
                }
                p=stack.pop();
            }
            //处理右子树
            stack.push(p);
            p=p.rightChild;
        }
    }
}

6. 反转链表

    public ListNode ReverseList(ListNode head) {
        if (head==null){
            return null;
        }
        ListNode pre=null;
        ListNode next=null;
        while(head!=null){
            next=head.next;
            head.next=pre;
            pre=head;
            head=next;
        }
        return pre;
    }

7. 输入前序遍历和中序遍历重建二叉树

/**
 * @Date: 2019/3/15 16:11
 */
public class Solution {
    public TreeNode reConstructBinaryTree(int[] pre, int[] in) {
        TreeNode root = constructTree(pre, 0, pre.length - 1, in, 0, in.length - 1);
        return root;
    }

    private TreeNode constructTree(int[] pre, int startPre, int endPre, int[] in, int startIn, int endIn) {
        if (startIn>endIn||startPre>endPre){
            return null;
        }
        TreeNode root=new TreeNode(pre[startPre]);
        for (int i = startIn; i <= endIn; i++) {
            if (in[i] ==pre[startPre]){
                root.left=constructTree(pre,startPre+1,startPre+i-startIn,in,startIn,i-1);
                root.right=constructTree(pre,i-startIn+startPre+1,endPre,in,i+1,endIn);
                break;
            }
        }
       return root; 
    }
}

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int x) {
        val = x;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值