面试算法题

4.1 基础算法

4.1.1 冒泡排序

for(int i = 0; i < arr.length - 1; i++){
    for(int j = 0; j < arr.length - 1 - i; j++){
        if(arr[j] > arr[j + 1]){
            int temp = arr[j];
            arr[j] = arr[j + 1];
            arr[j + 1] = temp;
        }
    }    
}

4.1.2 二分查找

public static int binSearch(int[] array, int target){
    int low = 0, high = array.length, mid = 0;
    while(low <= high){
        mid = low + (high - low) / 2;
        if(array[mid] == target){
            return mid;
        }else if(target > array[mid]){
            low = mid + 1;
        }else{
            high = mid - 1;
        }
    }
    return -1;
}

4.1.3 插入排序

public static int[] insertSort(int[] arr){
    // 取出未排序的第一个元素
    for(int i = 1; i < arr.length; i++){
        int value = arr[i]; // 取出未排序的第一个元素
        int index = i - 1; // 已排序的最后一个位置
        while(index >= 0 && value < arr[index]){
            // 未排序的第一个元素小于已排序的元素(从后往前)
            arr[index + 1] = arr[index]; // 原来排序的元素移动到后边
            index--; // index指向已排序的元素,从后往前移动地插入
        }
        arr[index + 1] = value; // 将元素插入到刚好arr[x]的前边。
    }
    
    return arr;
}

public static int[] insertSort(int[] arr){
    for(int i = 1; i < arr.length; i++){
        int value = arr[i];
        int index = i - 1;
        while(index >= 0 && value < arr[index]){
            arr[index + 1] = arr[index--];
        }
        arr[index + 1] = value;
    }
    return arr;
}

4.1.4 快速排序

public static void quickSort(int[] arr, int low, int high){
    if(low < high){
        int pivot = partition(arr,low,high);
        quickSort(arr,low,pivot - 1);
        quickSort(arr,pivot + 1, high);
    }
}

private static int partition(int[] arr, int low, int high){
    int pivot = arr[high];

    while(low < high){
        while(low < high && arr[low] < pivot){
            low++;
        }
        arr[high] = arr[low];
        while(low < high && arr[high] >= pivot){
            high--;
        }
        arr[low] = arr[high];
    }

    arr[high] = pivot;

    return high;
}

4.1.5 归并排序

package study.sort;

public class Merge {
    //归并排序所需要的辅助数组
    private static Comparable[] assist;

    //对数组内的元素进行排序
    public static void sort(Comparable[] a){
        assist = new Comparable[a.length];
        int lo = 0;
        int hi = a.length - 1;
        sort(a,lo,hi);
    }

    //对数组a中从索引lo到索引hi之间的元素进行排序
    private static void sort(Comparable[] a,int lo,int hi){
        //只有一个数据,不用排序了
        if (hi <= lo){
            return;
        }

        int mid = lo + (hi - lo) / 2;

        //对lo到mid之间的元素进行排序
        sort(a,lo,mid);
        //对mid + 1到hi之间的元素进行排序
        sort(a,mid + 1,hi);
        //对lo到mid这组数据和mid到hi这组数据进行归并
        merge(a,lo,mid,hi);
    }

    //从索引lo到所以mid为一个子组,从索引mid+1到索引hi为另一个子组,
    // 把数组a中的这两个子组的数据合并成一个有序的大组(从索引lo到索引hi)
    private static void merge(Comparable[] a,int lo,int mid,int hi){
        //lo到mid这组数据和mid + 1到hi这组数据归并到辅助数组assist对应的索引处
        int i = lo;//定义一个指针,指向assist数组中开始填充数据的索引
        int p1 = lo;//定义一个指针,指向第一组数据的第一个元素
        int p2 = mid + 1;//定义一个指针,指向第二组数据的第一个元素

        //比较左边小组和右边小组中的元素大小,哪个小,就把哪个数据填充到assist数组中
        while (p1 <= mid && p2 <= hi){
            if (less(a[p1],a[p2])){
                assist[i++] = a[p1++];
            }else {
                assist[i++] = a[p2++];
            }
        }

        //上面的循环结束后,如果退出循环的条件是p1 > mid,则证明左边小组中的数据已经归并完毕,
        // 如果退 出循环的条件是p2 > =hi,则证明右边小组的数据已经填充完毕;
        // 所以需要把未填充完毕的数据继续填充到assist中,
        // 下面两个循环,只会执行其中的一个
        while (p1 <= mid){
            assist[i++] = a[p1++];
        }
        while (p2 <= hi){
            assist[i++] = a[p2++];
        }

        //那么现在,assist数组中,从lo到hi的元素是有序的,再把数据拷贝到a数组中对应的索引处
        for (int index = lo; index <= hi ; index++) {
            a[index] = assist[index];
        }
    }


    //判断v是否小于w
    private static boolean less(Comparable v, Comparable w) {
        return v.compareTo(w) < 0;
    }

    //交换a数组中,索引i和索引j处的值
    private static void exchange(Comparable[] a, int i, int j) {
        Comparable temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
}


4.2 综合

4.2.1 LRU


class LRUCache {

    private Map<Integer,Node> map;
    private Node head, tail;
    private Integer capacity;

    public LRUCache(int capacity) {
        this.capacity = capacity;
        map = new HashMap();
        head = new Node(-1,-1);
        tail = new Node(-1,-1);
        head.next = tail;
        tail.pre = head;
    }
    
    public int get(int key) {
        if(map.containsKey(key)){
            Node temp = map.get(key);
            cutNode(temp);
            insertHead(temp);
            return temp.val;
        }
        return -1;
    }
    
    public void put(int key, int value) {
        Node temp = new Node(key,value);
        if(map.containsKey(key)){
            Node node = map.get(key);
            cutNode(node);
        }else if(map.size() >= capacity){
            map.remove(cutNode(node).key);
        }
        map.put(key,temp);
        insertHead(temp);
    }

    private class Node{
        Node pre;
        Node next;
        int val;
        int key;
        
        Node(int key, int val){
            this.key = key;
            this.val = val;
        }
    }

    private void cutNode(Node temp){
        temp.pre.next = temp.next;
        temp.next.pre = temp.pre;
        temp.pre = null;
        temp.next = null;
    }

    private void insertHead(Node temp){
       temp.next = head.next;
       head.next.pre = temp;
       head.next = temp;
       temp.pre = head;
    }

}

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache obj = new LRUCache(capacity);
 * int param_1 = obj.get(key);
 * obj.put(key,value);
 */

4.2.2 判断一棵树是否是平衡二叉树

public class IsBBT{
    
}

4.2.3 反转一个链表

public class LinkedListReversal{
    
    class ListNode{
        ListNode next;
        int val;
        public ListNode(int val){
            this.val = val;
        }
    }
    
    public static ListNode reverse(ListNode head){
        if(head == null) return head;
        ListNode pre = null, cur = head;
        while(cur != null){
            ListNode temp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = temp;
        }
        return pre;
    }
    
    
    public static void printList(ListNode head){
        while(head != null){
            System.out.print(head.val + " ");
            head = head.next;
        }
        System.out.println();
    }
    
    public static void main(String[] args){
        ListNode head = new ListNode(1);
        head.next = new ListNode(2);
        head.next.next = new ListNode(3);
        printList(head);
        ListNode reverse = reverse(head);
        printList(reverse);
    }
}

4.2.4 实现一个hash表

// table = ArrayList<Entry>();
// hash(key) Math.abs(key.hashCode()) % table.size
/// 

4.2.4 找出两个链表的交点

class ListNode{
    ListNode next;
    int val;
    public ListNode(int val){
        this.val = val;
    }
}
public class LinedListIntersection{

    public static ListNode find(ListNode l1, ListNode l2){
        ListNode cur1 = l1, cur2 = l2;
        while(cur1 != cur2){
            cur1 = cur1 == null ? l2 : cur1.next;
            cur2 = cur2 == null ? l1 : cur2.next;
        }
        return cur1;
    }
}

4.2.5 监测单链表中是否有环

// 快慢指针
public class LinkedNode{
	private int val;
    private LinkedNode next;
    public LinkedNode(int val){
        this.val = val;
    }
    
    public static boolean isCircle(LinkedList head){
        LinkedNode slow = head, fast = head;
        while(slow != fast && fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
        }
        
        return fast != null;
    }
}

4.2.6 实现一个图和DFS以及BFS

class Graph{
    private Map<Integer, List<Integer>> graph;
    public Graph() {
        graph = new HashMap<>();
    }

    public void addEdge(int v, int w) {
        graph.computeIfAbsent(v, k -> new ArrayList<>()).add(w);
        graph.computeIfAbsent(w, k -> new ArrayList<>()).add(v);
    }

    public void DFS(int start) {
        Set<Integer> visited = new HashSet<>();
        dfsUtil(start,visited);
    }
    private void dfsUtil(int v, Set<Integer> visited) {
        System.out.println("dfs: " + v);
        visited.add(v);
        List<Integer> neighbors = graph.get(v);
        for (Integer neighbor : neighbors) {
            if (!visited.contains(neighbor)) {
                dfsUtil(neighbor, visited);
            }
        }
    }

    public void BFS(int start) {
        Queue<Integer> queue = new LinkedList<>();
        Set<Integer> visited = new HashSet<>();
        queue.add(start);
        visited.add(start);
        while (!queue.isEmpty()) {
            Integer temp = queue.poll();
            System.out.println("BFS: " + temp);
            List<Integer> neighbors = graph.get(temp);
            for (Integer neighbor : neighbors) {
                if(!visited.contains(neighbor)) {
                    visited.add(neighbor);
                    queue.add(neighbor);
                }
            }
        }
    }

}

4.2.7 给定一个数组,找出其中最大子数组和

class MaxSubArray{
    public static int maxSubArray(int[] arr){
        int max = Integer.MIN_VALUE;
        int sum = 0;
        for(int i = 0; i  < arr.length; i++){
            sum = sum < 0 ? arr[i] ? arr[i] + sum;
            max = Math.max(max, sum);
        }
        return max;
    }
}

4.2.8 实现二叉树的中、前、后序遍历

// 前序:根左右
// 中序:左根右
// 后序:左右根

4.2.9 找出一个字符串的最长回文串

class MaxABA{
    public class find(String s){
        int maxLen = 0, start = 0;
        for(int i = 0; i < s.length(); ){
            int l = i, r = i;
            while(r + 1 < s.length() && s.charAt(r) == s.charAt(r + 1)){
                r++;
            }
            i = r + 1;
            while(l > 0 && r < s.length() - 1 && s.charAt(l-1) == s.charAt(r + 1)){
                l--;
                r++;
            }
            if(r - l + 1 > maxLen){
                start = l;
                maxLen = r - l + 1;
            }
        }
        return s.substring(start, maxLen);
    }
}

4.2.10 两数之和

public class TwoSum{
    public static int[] twoSum(int[] arr, target){
        Map<Integer,Integer> map = new HashMap();
        for(int i = 0; i < arr.length; i++){
            int temp = target - arr[i];
            if(map.contains(temp)){
                return new int[]{map.get(temp), i};
            }
            map.put(arr[i], i);
        }
        return new int[2];
    }
}

4.2.11 基于数组的栈

public class ArrayStack{
    private int capacity;
    private int top;
    private int array;
    public ArrayStack(int cap){
        this.capacity = cap;
        top = -1;
        array = new int[cap];
    }
    
    public int pop(){
        if(isEmpty()){
            throw new IllegalStateException("Stack is empty");
        }
        return array[top--];
    }
    public int peek(){
        if(isEmpty()){
            throw new IllegalStateException("Stack is empty");
        }
        return array[top];
    }
    public int push(int val){
        if(isFull()){
            throw new StackOverflowError("Stack is full");
        }
        return array[++top];
    }
    
    public boolean isEmpty(){
        return top == -1;
    }
    pulbic boolean isFull(){
        return top == capacity - 1;
    }
    
    public int size(){
        return top + 1;
    }
    
    
}

4.2.12 二叉树层序遍历

class TreeNode{
    TreeNode left;
    TreeNode right;
    int val;
    public TreeNode(int val){
        this.val = val;
    }
    
    public static void OrderTraversal(TreeNode root){
        if(root == null) return;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        while(!queue.isEmpty()){
            TreeNode temp = queue.poll();
            // sout(temp) 访问该节点
            if(temp.left != null) queue.add(temp.left);
            if(tmep.right != null) queue.add(temp.right);
        }
    }
}


4.2.13 排序数组中查找值,如果没有则返回应该插入的位置

public class BinSearch{
    public static int find(int[] arr, int target){
        int low = 0, high = arr.length - 1;
        while(low <= high){
            int mid = low + (high - low) / 2;
            if(arr[mid] == target){
                return mid;
            }else if(arr[mid] < target){
                low = mid + 1;
            }else {
                high = mid - 1;
            }
        }
        return low;
    }
}
posted @ 2025-10-18 13:30  飞↑  阅读(11)  评论(0)    收藏  举报