常见面试数据结构和算法题(持续中...)

215 阅读2分钟

一、数据结构

二、算法

1、使用栈,构造队列。

class MyQueue {

    private Stack<Integer> s1;
    private Stack<Integer> s2;
    private int front;
    
    public MyQueue() {
        s1 = new Stack();
        s2 = new Stack();
    }
    
    // 入队:新元素放在栈底
    public void push(int x) {
        if(s1.isEmpty()){
            front = x;
        }
        while(!s1.isEmpty()){
            s2.push(s1.pop());
        }
        s2.push(x);
        while(!s2.isEmpty()){
            s1.push(s2.pop());
        }
    }
    // 弹出队首的元素
    public int pop() {
        int result = s1.pop();
        if(!s1.isEmpty()){
            front = s1.peek();    
        }
        return result;
    }
    // 获取队首的元素
    public int peek() {
        return front;
    }
    
    public boolean empty() {
        return s1.isEmpty();
    }
}

2、设计一个支持 push,pop,top,getMin 操作,检索到最小元素的栈。

class MinStack {

    Stack<Integer> s1;
    Stack<Integer> s2;
    
    /** initialize your data structure here. */
    public MinStack() {
        s1 = new Stack<>();
        s2 = new Stack<>();
    }
    
    public void push(int x) {
        s1.push(x);
        
        if(s2.isEmpty() || s2.peek() >= x){
             s2.push(x);
        }
    }
    
    public void pop() {
        int temp = s1.pop();
        if(!s2.isEmpty() && temp == s2.peek()){
            s2.pop();
        }
    }
    
    public int top() {
        return s1.peek();
    }
    
    public int getMin() {
        return s2.peek();
    }
}

  • 队列

  • 哈希表

1、给定一个未排序的整数数组,找出最长连续序列的长度。要求算法的时间复杂度为 O(n)。

class Solution {
    public int longestConsecutive(int[] nums) {
        Set<Integer> set = new HashSet<>();
        
        for(int num : nums){
            set.add(num);
        }
        int temp = 0;
        for(int num : nums){
            if(!set.contains(num - 1)){
                int currentNum = num;
                int longestNum = 1;
                while(set.contains(currentNum + 1)){
                    currentNum++;
                    longestNum++;
                }
                temp = Math.max(temp, longestNum);
            }
        }
        
        return temp;
    }
}
  • 动态规划

  • 递归

  • 二分法

  • 排序

  • 字符串

1. 反转字符串
class Solution {
    public void reverseString(char[] s) {
      int j = s.length - 1; 
      
      for(int i = 0; i < s.length/2; i++){
        char temp = s[i]; 
        s[i] = s[j];
        s[j] = temp;
        j--;
      }
      
    }
}

2、寻找最大不重复子字符串
class Solution {
    public int lengthOfLongestSubstring(String s) {
      int num = 0;
      for(int i = 0; i < s.length(); i++){
        for(int j = i + 1; j <= s.length(); j++){

            if(unique(s, i, j)){
              num = Math.max(num, j - i);
            }

        }
      }
      
      return num;
    }
  
  private boolean unique(String s, int start, int end){
    HashSet<Character> set = new HashSet<>();
    for(int i = start; i < end; i++){
       Character temp = s.charAt(i); 
      if(set.contains(temp)){
        return false;
      }
      set.add(temp);
    }
    return true;
  }
  
  
}
3、寻找最大不重复子字符串(解法2)
class Solution {
    public int lengthOfLongestSubstring(String s) {
      int length = s.length();
      int i = 0;
      int j = 0;
      HashSet<Character> set = new HashSet<>();
      int num = 0;
      while(i < length && j < length){
        if(!set.contains(s.charAt(j))){
          set.add(s.charAt(j++));
          num = Math.max(num, j - i);
        }else{
          set.remove(s.charAt(i++));
        }
      }
      return num;
    }
}


4、罗马数字和十进制转换?

class Solution {
    public int romanToInt(String s) {
       char [] strs = new char[s.length()];
        int count = 0;
        int prev = 0;
        for (int i = 0; i < s.length(); i++) {
            strs[i] = s.charAt(i);
        }
        for (int i = strs.length - 1; i > -1; i--) {

            switch(strs[i]){
                case 'I' :
                    if (1 < prev){
                        count -= 1;
                    }else {
                        count += 1;
                    }
                    prev = 1;
                    break;
                case 'V' :
                    if (5 < prev){
                        count -= 5;
                    }else {
                        count += 5;
                    }
                    prev = 5;
                    break;
                case 'X' :
                    if (10 < prev){
                        count -= 10;
                    }else {
                        count += 10;
                    }
                    prev = 10;
                    break;
                case 'L' :
                    if (50 < prev){
                        count -= 50;
                    }else {
                        count += 50;
                    }
                    prev = 50;
                    break;
                case 'C' :
                    if (100 < prev){
                        count -= 100;
                    }else {
                        count += 100;
                    }
                    prev = 100;
                    break;
                case 'D' :
                    if (500 < prev){
                        count -= 500;
                    }else {
                        count += 500;
                    }
                    prev = 500;
                    break;
                case 'M' :
                    if (1000 < prev){
                        count -= 1000;
                    }else {
                        count += 1000;
                    }
                    prev = 1000;
                    break;
            }

        }
        return count;
    }
}

  • 多线程
1、按顺序打印
class Foo {

    private boolean firstFlag = false;
    private boolean secondFlag = false;
    
    private Object lock = new Object();
    
    public Foo() {
        
    }

    public void first(Runnable printFirst) throws InterruptedException {
        synchronized(lock){
            firstFlag = true;
            printFirst.run();
            lock.notifyAll();
        }
    }

    public void second(Runnable printSecond) throws InterruptedException {
        synchronized(lock){
            while(!firstFlag){
                lock.wait();
            }
            secondFlag = true;
            printSecond.run();
            lock.notifyAll();
        }
    }

    public void third(Runnable printThird) throws InterruptedException {
        synchronized(lock){
            while(!secondFlag){
                lock.wait();
            }
            printThird.run();
        }     
    }
}