面试算法

快速排序

https://my.oschina.net/mup/blog/362210


public static void quickSort(int[] arr){
    qsort(arr, 0, arr.length-1);
}
private static void qsort(int[] arr, int low, int high){
    if (low < high){
        int pivot=partition(arr, low, high);        //将数组分为两部分
        qsort(arr, low, pivot-1);                   //递归排序左子数组
        qsort(arr, pivot+1, high);                  //递归排序右子数组
    }
}
private static int partition(int[] arr, int low, int high){
    int pivot = arr[low];     //枢轴记录
    while (lowwhile (low=pivot) --high;
        arr[low]=arr[high];             //交换比枢轴小的记录到左端
        while (low//交换比枢轴小的记录到右端
    }
    //扫描完成,枢轴到位
    arr[low] = pivot;
    //返回的是枢轴的位置
    return low;
}

冒泡排序

冒泡排序

1:基本思路:对未排序的各元素从头到尾依次比较相邻的两个元素是否逆序(与欲排顺序相反),若逆序就交换这两元素,经过第一轮比较排序后便可把最大(或 最小)的元素排好,然后再用同样的方法把剩下的元素逐个进行比较,就得到所要的顺序。
2:效率:比较和交换次数都为O(N的平方)

public static void bubbleSort1(int[] datas) {
        // 同样为控制循环次数,这样可以让内层减少比较次数
        for (int i = datas.length - 1; i > 0; i--) {
            for (int j = 0; j < i; j++) {
                if (datas[j] > datas[j + 1]) {
                    swapData(datas, j, j + 1);
                }
            }
        }
    }

插入排序

插入法排序
1:基本思路:每拿到一个元素,都要将这个元素与所有它之前的元素遍历比较一遍, 让符合排序顺序的元素挨个移动到当前范围内它最应该出现的位置。
2:效率:比较和交换次数都为O(N的平方),大致为N*(N-1)/4,所以这个算法比冒泡大致快一倍,比选择排序略快,尤其是部分数据已经局部有序的情况下,这个 算法效率会更高

插入排序最最关键的点要知道,其实它是对一个已经排序好的列表在排序。例如来了一个新值,要插入到这个已经排序好的列表内,插入到哪呢,就是要用插入排序。不过,如果整个列表都是乱的怎么办,可以先拿第二个做基准,然后前两个比,前三个比,前四个比这个样子的。

// 插入排序,算林称最亲民的排序算法,插入排序采用最简单的插入方式对一个整数数组进行排序。
    // 它循环数组中从第二个开始的所有元素,并且将每一个循环到的元素插入到相应的位置,从而实现排序的目的。
    public void insertSort(int[] as){
        //假定第一个位置是排好序
        int j = 0;
        for(int i=1;i < as.length;i++){
            int temp = as[i];
            for(j=i;j>0;j--){
                if(as[j-1] >= temp){
                    as[j] = as[j-1];
                }else{
                    break;
                }
            }
            //这个j就是上个循环结束的值
            as[j] = temp;
        }
    }

选择排序

选择排序
1:基本思路:从所有元素中选择一个最小元素a[i]放在a[0] 即让最小元素a[i]与 a[0]交换 ,作为第一轮;
第二轮是从a[1]开始到最后的各个元素中选择一个最 小元素,放在a[1]中;……依次类推。n个数要进行(n-1)轮

2:效率:交换次数减少到O(N),但是比较次数仍为O(N的平方)

/**
     * 按照顺序,每次找出最小位置的索引
     * @param datas
     */
    public static void selectSort(int[] datas){
        for (int i = 0; i < datas.length - 1; i++) {
            int minIndex = i;
            for (int j = i + 1; j < datas.length; j++) {
                if (datas[minIndex] > datas[j]) {
                    minIndex = j;
                }
            }
            //找出最小位置之后,把它与前面的交换
            swapData(datas,minIndex, i);
        }
    }

    public static void swapData(int[] datas,int aIndex,int bIndex){
        int temp = datas[bIndex];
        datas[bIndex] = datas[aIndex];
        datas[aIndex] = temp;
    }

堆排序

二叉树

前序中序后序遍历

层次遍历

二分查找


/** 
 * 递归方法实现二分查找法. 
 * @param Array数组 
 * @param low 数组第一位置 
 * @param high 最高 
 * @param key 要查找的值. 
 * @return 返回值. 
 */  
int BinSearch(int Array[],int low,int high,int key)  
{  
    if (low<=high)  
    {  
        int mid = (low+high)/2;  
        if(key == Array[mid])  
            return mid;  
        else if(key//移动low和high  
            return BinSearch(Array,low,mid-1,key);  
        else if(key>Array[mid])  
            return BinSearch(Array,mid+1,high,key);  
    }  
    else  
        return -1;  
}  
/* 
     * 非递归二分查找算法 
     * 参数:整型数组,需要比较的数. 
     */  
    public static int binarySearch(Integer[]srcArray,int des){  
        //第一个位置.  
        int low=0;  
        //最高位置.数组长度-1,因为下标是从0开始的.  
        int high=srcArray.length-1;  
        //当low"指针"和high不重复的时候.  
        while(low<=high){  
            //中间位置计算,low+ 最高位置减去最低位置,右移一位,相当于除2.也可以用(high+low)/2  
            int middle=low+((high-low)>>1);  
        //与最中间的数字进行判断,是否相等,相等的话就返回对应的数组下标.  
        if(des==srcArray[middle]){  
            return middle;  
        //如果小于的话则移动最高层的"指针"  
        }else if(des1;  
        //移动最低的"指针"   
        }else{  
            low=middle+1;  
            }  
        }  
        return-1;  
        }  

}  

字母和数字排序

private static void sortString() {
        String text = "qw3e1";
        char[] charArray = text.toCharArray();
        int[] asciiCode = new int[charArray.length];
        for (int i = 0; i <= charArray.length - 1; i++) {
            // charArray[i]默认是输出该位置的字符,如果你要得到它的ascii就强转int
            // System.out.println((int) charArray[i]);
            asciiCode[i] = (int) charArray[i];
            System.out.println(asciiCode[i]);
        }

        // 排序ascii
        for (int i = 0; i <= asciiCode.length - 1; i++) {
            int minIndex = i;
            for (int j = i + 1; j < asciiCode.length; j++) {
                if (asciiCode[minIndex] > asciiCode[j]) {
                    minIndex = j;
                }
            }
            //找出最小位置之后,把它与前面的交换
            swapData(asciiCode,minIndex, i);
        }

        System.out.println("=============================");

        //再转为字符
        for (int i = 0; i <= asciiCode.length - 1; i++) {
            System.out.println((char)asciiCode[i]);
        }

    }

100以内的质数

质数(prime number)又称素数,有无限个。一个大于1的自然数,除了1和它本身外,不能被其他自然数整除(除0以外)的数称之为素数(质数);否则称为合数.

因为一个数要被整除,肯定是小于或者等于它一半的数,如果比它一半大的数肯定不能整除。

public class PrimeNumber {

    public static void main(String[] args) {
        for (int i = 2; i <= 100; i++) {
            boolean flag = false;
            for (int j = 2; j <= i/2; j++) {
                if (i % j == 0) {
                    flag = true;
                    break;
                }
            }
            if (!flag) {
                System.out.println("xx "+i);
            }
        }
    }

}

两个日期内相隔和相差天数

http://blog.csdn.net/wpydaguan/article/details/46235349

一个绳子从一头开始烧是1小时,要求想办法测出45分钟。

同事点燃两根绳子,一根点一头,另外一根点两头,待两头都点的烧完(此时已过30分钟)立即把一头点的那一根的另外一头也点着,烧完后正好45分钟

英文文本中计算每个单词出现的次数

把文本字符串进行.charArray。这样就返回一个char[]数组。key为字母,value为一个AtomicInteger。可以动态的改变value的内容。

将文本的单词切割并维护到一个MAP中,已单词为KEY 对应的VALUE为这个单词出现的次数,然后启用多线程,结合方法1 进行 查找计算。

你可能感兴趣的:(面试算法)