大厂代码面手撕基础题

发布时间:2024年01月18日


不要纠结,干就完事了,熟练度很重要!!!多练习,多总结!!!

快速排序

代码实现

class Solution {
    public int[] sortArray(int[] nums) {
        sort(nums, 0, nums.length-1);
        return nums;
    }

    public void sort(int[] nums, int lo, int hi){
        if(lo > hi){
            return ;
        }

        int j = partition(nums, lo, hi);
        sort(nums, lo, j-1);
        sort(nums, j+1, hi);
    }

    public int partition(int[] nums, int lo, int hi){
        int pivot = nums[lo];
        int i = lo+1, j = hi;
        while(i <= j){
            while(i < hi && nums[i] < pivot){
                i++;
            }

            while(j > lo && nums[j] > pivot){
                j--;
            }
            if(i >= j){
                break;
            }
            swap(nums, i, j);
        }
        swap(nums, lo, j);
        return j;
    }

    public void swap(int[] nums, int i, int j){
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
}

归并排序

代码实现

class Solution {
    int[] temp;
    public int[] sortArray(int[] nums) {
        temp = new int[nums.length];
        sort(nums, 0, nums.length-1);
        return nums;
    }

    public void sort(int[] nums, int low, int high){
        if(low >= high){
            return;
        }
        int mid = low + (high-low)/2;
        sort(nums, low, mid);
        sort(nums, mid+1, high);
        merge(nums, low, mid, high);

    }

    public void merge(int[] nums, int low, int mid, int high){
        for(int i = low; i <= high ;i++){
            temp[i] = nums[i];
        }

        int i = low, j = mid+1;
        for(int k = low;k <= high;k++){
            if(i == mid + 1){
                nums[k] = temp[j++];
            }else if(j == high+1){
                nums[k] = temp[i++];
            }else if(temp[i] > temp[j]){
                nums[k] = temp[j++];
            }else {
                nums[k] = temp[i++];
            }
        }
    }
}

单例模式

代码实现

懒汉式:
双重校验,线程安全且在多线程情况下能保持高性能。

public class Singleton {  
    private volatile static Singleton singleton;  
    private Singleton (){}  
    public static Singleton getSingleton() {  
	    if (singleton == null) {  
	        synchronized (Singleton.class) {  
	            if (singleton == null) {  
	                singleton = new Singleton();  
	            }  
	        }  
	    }  
	    return singleton;  
    }  
}

饿汉式:
线程安全,在程序启动时直接运行加载,但是可能造成资源浪费。

public class Singleton {  
    private static Singleton instance = new Singleton();  
    private Singleton (){}  
    public static Singleton getInstance() {  
   		return instance;  
    }  
}

LRU Cache

代码实现

public class LRUCache {
   class LinkedNode {
     int key;
     int value;
     LinkedNode prev;
     LinkedNode next;
   }
 
  private void addNode(LinkedNode node) {
    node.prev = head;
    node.next = head.next;
    head.next.prev = node;
    head.next = node;
  }

  private void removeNode(LinkedNode node){
    LinkedNode prev = node.prev;
    LinkedNode next = node.next;
    prev.next = next;
    next.prev = prev;
  }

  private void moveToHead(LinkedNode node){
    removeNode(node);
    addNode(node);
  }

  private LinkedNode popTail() {
    LinkedNode res = tail.prev;
    removeNode(res);
    return res;
  }

  private Hashtable<Integer, LinkedNode> cache = new Hashtable<Integer,LinkedNode>();
  private int size;
  private int capacity;
  private LinkedNode head, tail;

  public LRUCache(int capacity) {
    this.size = 0;
    this.capacity = capacity;
    head = new LinkedNode();
    tail = new LinkedNode();
    head.next = tail;
    tail.prev = head;
  }

  public int get(int key) {
    LinkedNode node = cache.get(key);
    if (node == null) return -1;
    moveToHead(node);
    return node.value;
  }

  public void put(int key, int value) {
    LinkedNode node = cache.get(key);

    if(node == null) {
      LinkedNode newNode = new LinkedNode();
      newNode.key = key;
      newNode.value = value;
      cache.put(key, newNode);
      addNode(newNode);
      ++size;
      if(size > capacity) {
        LinkedNode tail = popTail();
        cache.remove(tail.key);
        --size;
      }
    } else {
      node.value = value;
      moveToHead(node);
    }
  }
}

生产者消费者模式

代码实现

class ProducerConsumer {
 
   private int maxSize;
   private LinkedList<Object> storage;
 
   public ProducerConsumer(int size) {
       this.maxSize = size;
       storage = new LinkedList<>();
   }
 
   public synchronized void put() throws InterruptedException {
       while (storage.size() == maxSize) {
           storage.wait();
       }
       storage.add(new Object());
       storage.notifyAll();
   }
 
   public synchronized void take() throws InterruptedException {
       while (storage.size() == 0) {
           storage.wait();
       }
       System.out.println(storage.remove());
       storage.notifyAll();
   }
}


阻塞队列

代码实现

public class BlockingQueue<E> {
    /**
     * 阻塞队列最大容量
     */
    private int size;

    /**
     * 队列底层实现
     */
    LinkedList<E> list = new LinkedList<>();

    ReentrantLock lock = new ReentrantLock();

    /**
     * 队列满的等待条件
     */
    Condition full = lock.newCondition();

    /**
     * 队列空的等待条件
     */
    Condition empty = lock.newCondition();

    public BlockingQueue(int size) {
        this.size = size;
    }


    public void enqueue(E e) throws InterruptedException {
        lock.lock();
        try {
            // 队列满了,就在full条件上进行等待
            while (list.size() == size){
                full.await();
            }

            list.add(e);
            System.out.println("入队:"+e);
            // 入队之后,就通知在empty条件下等待的线程
            empty.signal();
        } finally {
            lock.unlock();
        }
    }

    public E dequeue() throws InterruptedException {
        E e;
        lock.lock();
        try {
            // 队列为空,就在空条件上等待
            while (list.size() == 0){
                empty.await();
            }
            e = list.removeFirst();
            System.out.println("出队:"+e);
            // 出队之后,就通知在full条件下等待的线程
            full.signal();
            return e;
        } finally {
            lock.unlock();
        }
    }
}

多线程按序打印

三个不同的线程 A、B、C 将会共用一个 Foo 实例。

线程 A 将会调用 first() 方法
线程 B 将会调用 second() 方法
线程 C 将会调用 third() 方法

代码实现

class Foo {
    private int i = 1;
    private int n = 3;


    public Foo() {
        
    }

    public void first(Runnable printFirst) throws InterruptedException {
        while(i <= n){
            synchronized(this){
                if(i <= n && i % 3 == 1){
                    printFirst.run();
                    i++;
                }
            }
        }
        
    }

    public void second(Runnable printSecond) throws InterruptedException {
        while(i <= n){
            synchronized(this){
                if(i <= n && i % 3 == 2){
                    printSecond.run();
                    i++;
                }
            }
        }
    }

    public void third(Runnable printThird) throws InterruptedException {
        while(i <= n){
            synchronized(this){
                if(i <= n && i % 3 == 0){
                    printThird.run();
                    i++;
                }
            }
        }
    }
}

class Foo {
    private int i = 1;
    private int n = 3;

    private Lock lock = new ReentrantLock();

    public Foo() {
        
    }

    public void first(Runnable printFirst) throws InterruptedException {
        while(i <= n){
            lock.lock();
            try{
                if(i <= n && i % 3 == 1){
                    printFirst.run();
                    i++;
                }
            }finally{
                lock.unlock();
            }
        }
        
    }

    public void second(Runnable printSecond) throws InterruptedException {
        while(i <= n){
            lock.lock();
            try{
                if(i <= n && i % 3 == 2){
                    printSecond.run();
                    i++;
                }
            }finally{
                lock.unlock();
            }
        }
    }

    public void third(Runnable printThird) throws InterruptedException {
        while(i <= n){
            lock.lock();
            try{
                if(i <= n && i % 3 == 0){
                    printThird.run();
                    i++;
                }
            }finally{
                lock.unlock();
            }
        }
    }
}

多线程交替打印字符串

编写一个可以从 1 到 n 输出代表这个数字的字符串的程序,但是:

如果这个数字可以被 3 整除,输出 “fizz”。
如果这个数字可以被 5 整除,输出 “buzz”。
如果这个数字可以同时被 3 和 5 整除,输出 “fizzbuzz”。

代码实现

class FizzBuzz {
    private int n;
    private int i = 1;
    private Lock lock = new ReentrantLock();


    public FizzBuzz(int n) {
        this.n = n;
    }

    // printFizz.run() outputs "fizz".
    public void fizz(Runnable printFizz) throws InterruptedException {        
        while(i <= n){
            lock.lock();
            try{
                if(i <= n && i % 3 == 0 && i % 5 != 0){                    
                    printFizz.run();
                    i++;
                }                
            }finally{
                lock.unlock();
            }
        }
    }

    // printBuzz.run() outputs "buzz".
    public void buzz(Runnable printBuzz) throws InterruptedException {
        while(i <= n){
            lock.lock();
            try{
                if(i <= n && i % 3 != 0 && i % 5 == 0){                    
                    printBuzz.run();
                    i++;
                }                
            }finally{
                lock.unlock();
            }
        }
        
    }

    // printFizzBuzz.run() outputs "fizzbuzz".
    public void fizzbuzz(Runnable printFizzBuzz) throws InterruptedException {
        while(i <= n){
            lock.lock();
            try{
                if(i <= n && i % 3 == 0 && i % 5 == 0){                    
                    printFizzBuzz.run();
                    i++;
                }                
            }finally{
                lock.unlock();
            }
        }
        
    }

    // printNumber.accept(x) outputs "x", where x is an integer.
    public void number(IntConsumer printNumber) throws InterruptedException {
        while(i <= n){
            lock.lock();
            try{
                if(i <= n && i % 3 != 0 && i % 5 != 0){                    
                    printNumber.accept(i);
                    i++;
                }                
            }finally{
                lock.unlock();
            }
        }
        
    }
}

class FizzBuzz {
    private int n;
    private int i = 1;
    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();


    public FizzBuzz(int n) {
        this.n = n;
    }

    // printFizz.run() outputs "fizz".
    public void fizz(Runnable printFizz) throws InterruptedException {
        while(i <= n){
            lock.lock();
            try{
                if(i % 3 == 0 && i % 5 != 0){                    
                    printFizz.run();
                    i++;
                    condition.signalAll();
                }else{
                    condition.await();
                }
            }finally{
               lock.unlock();
            }
        }
    }

    // printBuzz.run() outputs "buzz".
    public void buzz(Runnable printBuzz) throws InterruptedException {
        while(i <= n){
            lock.lock();
            try{
                if(i % 3 != 0 && i % 5 == 0){                    
                    printBuzz.run();
                    i++;
                    condition.signalAll();
                }else{
                    condition.await();
                }
            }finally{
               lock.unlock();
            }
        }
    }

    // printFizzBuzz.run() outputs "fizzbuzz".
    public void fizzbuzz(Runnable printFizzBuzz) throws InterruptedException {
        while(i <= n){
            lock.lock();
            try{
                if(i % 3 == 0 && i % 5 == 0){                    
                    printFizzBuzz.run();
                    i++;
                    condition.signalAll();
                }else{
                    condition.await();
                }
            }finally{
               lock.unlock();
            }
        }
    }

    // printNumber.accept(x) outputs "x", where x is an integer.
    public void number(IntConsumer printNumber) throws InterruptedException {
        while(i <= n){
            lock.lock();
            try{
                if(i % 3 != 0 && i % 5 != 0){                    
                    printNumber.accept(i);
                    i++;
                    condition.signalAll();
                }else{
                    condition.await();
                }
            }finally{
               lock.unlock();
            }
        }
        
    }
}

总结

觉得本博客有用的客官,可以给个点赞+收藏哦! 嘿嘿

喜欢本系列博客的可以关注下,以后除了会继续更新面试手撕代码文章外,还会出其他系列的文章!

文章来源:https://blog.csdn.net/weixin_43161461/article/details/135662071
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。