面試常問算法題總結

目錄

1 排序算法

2 二分查找

3 鏈表反轉

4 二分搜索樹遍歷

4.1 前序遍歷

4.2 中序遍歷

4.3 後序遍歷

4.4 層序遍歷

5 斐波那契數列

6 判斷鏈表是否有環

7 使用阻塞隊列來實現一個生產者消費者模型


1 排序算法

《常用排序算法總結》


2 二分查找

    public int binarySearch(int[] array, int target) {
        return binarySearch(array, 0, array.length - 1, target);
    }

    private int binarySearch(int[] array, int left, int right, int target) {
        if (left >= right) {
            return -1;
        }
        int mid = left + ((right - left) >>> 1);
        if (array[mid] == target) {
            return mid;
        } else if (array[mid] < target) {
            return binarySearch(array, mid + 1, right, target);
        } else {
            return binarySearch(array, left, mid, target);
        }
    }

3 鏈表反轉

public class MyLinkedList {

    private static class Node {

        private int value;
        private Node next;

        private Node(int value, Node next) {
            this.value = value;
            this.next = next;
        }

        @Override
        public String toString() {
            return Integer.toString(value);
        }
    }

    private Node head;

    private void addFirst(int value) {
        head = new Node(value, head);
    }

    public void reverse() {
        reverse(head);
    }

    private Node reverse(Node cur) {
        if (cur == null || cur.next == null) {
            head = cur;
            return cur;
        }
        Node nextNode = reverse(cur.next);
        nextNode.next = cur;
        cur.next = null;
        return cur;
    }

    @Override
    public String toString() {
        StringBuilder stringBuilder = new StringBuilder();
        for (Node cur = head; cur != null; cur = cur.next) {
            stringBuilder.append(cur).append("->");
        }
        stringBuilder.append("NULL");
        return stringBuilder.toString();
    }

    public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
        Random random = new Random();
        for (int i = 0; i < 10; i++) {
            myLinkedList.addFirst(random.nextInt(10));
        }
        System.out.println(myLinkedList);
        myLinkedList.reverse();
        System.out.println(myLinkedList);
    }
}

4 二分搜索樹遍歷

4.1 前序遍歷

public void preOrder() {
    preOrder(root);
}

private void preOrder(Node cur) {
    if (cur == null) {
        return;
    }
    System.out.print(cur.value + " ");
    preOrder(cur.left);
    preOrder(cur.right);
}

4.2 中序遍歷

public void inOrder() {
    inOrder(root);
}

private void inOrder(Node cur) {
    if (cur == null) {
        return;
    }
    inOrder(cur.left);
    System.out.print(cur.value + " ");
    inOrder(cur.right);
}

4.3 後序遍歷

public void postOrder() {
    postOrder(root);
}

private void postOrder(Node cur) {
    if (cur == null) {
        return;
    }
    postOrder(cur.left);
    postOrder(cur.right);
    System.out.print(cur.value + " ");
}

4.4 層序遍歷

public void levelOrder() {
    if (root == null) {
        return;
    }
    Queue<Node> queue = new LinkedList<>();
    queue.add(root);
    while (!queue.isEmpty()) {
        Node cur = queue.remove();
        System.out.print(cur.value + " ");
        if (cur.left != null) {
            queue.add(cur.left);
        }
        if (cur.right != null) {
            queue.add(cur.right);
        }
    }
}

5 斐波那契數列

public int fibonacci(int index) {
    if (index == 1 || index == 2) {
        return 1;
    } else {
        return fibonacci(index - 1) + fibonacci(index - 2);
    }
}

6 判斷鏈表是否有環

設置兩個快慢指針,一個步長爲1,另一個步長爲2。如果兩個指針最終相遇則說明鏈表有環:

public boolean isLoop() {
    if (head == null || head.next == null) {
        return false;
    }
    Node fast = head;
    Node slow = head;

    while (fast.next != null && fast.next.next != null) {
        fast = fast.next.next;
        slow = slow.next;

        if (fast == slow) {
            return true;
        }
    }
    return false;
}

7 使用阻塞隊列來實現一個生產者消費者模型

import java.util.concurrent.BlockingQueue;

public class Producer implements Runnable {

    private final BlockingQueue blockingQueue;

    public Producer(BlockingQueue blockingQueue) {
        this.blockingQueue = blockingQueue;
    }

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("produced:" + i);
            try {
                blockingQueue.put(i);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
import java.util.concurrent.BlockingQueue;

public class Consumer implements Runnable {

    private final BlockingQueue blockingQueue;

    public Consumer(BlockingQueue blockingQueue) {
        this.blockingQueue = blockingQueue;
    }

    @Override
    public void run() {
        while (true) {
            try {
                System.out.println("consumed:" + blockingQueue.take());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class ProducerConsumerTest {

    public static void main(String[] args) {
        BlockingQueue blockingQueue = new LinkedBlockingQueue();

        Thread producerThread = new Thread(new Producer(blockingQueue));
        Thread consumerThread = new Thread(new Consumer(blockingQueue));

        producerThread.start();
        consumerThread.start();
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章