java面试常考算法题记录

java面试常考算法题记录

 /**
     * 二分法查找非递归
     * @param arr
     * @param data
     * @return
     */
    public static int find(int[]arr,int data){
        int mid=0;
        int left=0;
        int right=arr.length-1;
        while (left<=right){
            mid=(right+left)/2;
            if(arr[mid]>data){
                right=mid-1;
            }else if(arr[mid]<data) {
                left=mid+1;
            }else {
                return arr[mid];
            }
        }
     return -1;
    }

    /**
     * 二分法查找递归
     * @param arr
     * @param data
     * @param left
     * @param right
     * @return
     */
    public static  int find(int[]arr,int data,int left,int right){
        if(left==right)return -1;
        int mid=(left+right)/2;
        if(arr[mid]==data) return arr[mid];
        return arr[mid]>data?find(arr,data,left,mid-1):find(arr,data,mid+1,right);
    }

    /**
     * 单链表反转递归
     * @param head
     * @return
     */
    public static Node  reverse(Node head){
        if(null==head||null==head.getNext()) return head;
        Node reHead = reverse(head.getNext());
        head.getNext().setNext(head);
        head.setNext(null);
        return reHead;
    }

    /**
     * 单链表反转非递归
     * @param head
     * @return
     */
    public static Node reverse1(Node head){
        if(null==head) return head;
        Node pre=head;
        Node cur=head.getNext();
        Node temp;
        while (null!=cur){
            temp=cur.getNext();
            cur.setNext(pre);
            pre=cur;
            cur=temp;
        }
        head.setNext(null);
        return pre;
    }

    /**
     * 打印链表到控制台
     * @param head
     */
    public static void printNode(Node head){
        while (null!=head.getNext()){
            System.out.print(head.getValue());
            System.out.print(",");
            head=head.getNext();
        }
        System.out.println(head.getValue());
    }
     /**
     * 快速排序 递归
     * @param arr 数组
     * @param left 左坐标 0
     * @param right 右坐标 length-1
     */
    public static void quickSort(int[]arr,int left,int right){
        if(arr.length==0) return;
        if(left>right) return;
        System.out.println("arr="+Arrays.toString(arr)+" ,left="+left+",right="+right);
        int index = midIndex(arr, left, right);
        quickSort(arr,left,index-1);
        quickSort(arr,index+1,right);
    }

    /**
     * 左右指针移动交换,返回下次递归分割点
     * @param arr 数组
     * @param left 左坐标
     * @param right 右坐标
     * @return 分割点
     */
    private static int midIndex(int[]arr,int left,int right){
    int mid=arr[left];
    System.out.println("mid="+mid);
    while (left<right){

        while (left<right&&arr[right]>=mid){
            right--;
        }
        arr[left]=arr[right];
        System.out.println("right move:"+Arrays.toString(arr));
        while (left<right&&arr[left]<mid){
            left++;
        }
        arr[right]=arr[left];
        System.out.println("left move:"+Arrays.toString(arr));
    }
    arr[left]=mid;
    return left;
}
//堆排序
public static void heapSort(int[] arr) {
        for (int i = arr.length / 2; i >= 0; i--) {//无序数组,调整为堆
            adjustHeap(arr, i, arr.length);
        }
        for (int i = arr.length - 1; i >= 0; i--) {
            int temp = arr[i];
            arr[i] = arr[0];
            arr[0] = temp;//交换堆顶和最后一个元素
            System.out.println(arr[i]);//输出最后一个元素
            adjustHeap(arr, 0, i); //剩余元素继续调整为堆
        }
    }
 /**
     * 调整生成堆
     *
     * @param arr    数组
     * @param parent 父节点坐标
     * @param length 调整堆数组长度
     */
    private static void adjustHeap(int[] arr, int parent, int length) {
        int child = 2 * parent + 1;//孩子索引=左孩子索引位置
        int temp = arr[parent];
        while (child < length) {//孩子节点索引小于数组长度,循环遍历堆

            if (child + 1 < length && arr[child] < arr[child + 1]) {//孩子索引+1小于数组长度(存在右孩子),且左孩子值小于右孩子值
                child++;//孩子索引移动到右孩子索引位置
            }
            if (temp > arr[child]) {//父节点值大于孩子节点,满足大根堆原则,退出循环
                break;
            }
            arr[parent] = arr[child];//如果父节点小于孩子节点,将孩子节点值赋给父节点
            parent = child;//父节点索引往下移动
            child = 2 * parent + 1;//孩子节点索引往下移动
        }

        arr[parent] = temp;//将初始父节点值赋给遍历到最后的父节点
    }
//最长回文,中心扩展法 时间复杂度O(n²),空间复杂度O(1)
    private static String longestPalindrome(String str){
        int start=0;//最长回文串开始位置
        int end=0;//最长回文串结束位置
        for(int i=0;i<str.length();i++){
            int index1 = maxLenght(str, i, i);//扩展搜索的中心落在字符上
            int index2=maxLenght(str,i,i+1);//扩展搜索的中心落在字符之间
            int len = Math.max(index1, index2);//两种情况下找到的回文串长度取最大的
            if(end-start<len){//如果此次遍历回文长度大于上次,重新计算回文串起始索引
                start=i-(len-1)/2;
                end=i+len/2;
            }
        }
        return str.substring(start,end);
    }
    //中心扩展,回文串长度
    private static int maxLenght(String str,int left,int right){
       while (left>=0&&right<str.length()&&str.charAt(left)==str.charAt(right)){//如果左右指针位置没有出界,并且左右指针处字符相等
           left--;//左指针左移
           right++;//右指针右移动
       }
        return right-left-1;//回文串长度
    }    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值