经典算法题总结:哈希表,栈,队列,堆篇

哈希表

哈希表这种 key,value 的集合结构可以在算法中实现记录的功能,并实现 O(1) 复杂度的查找。



3. 无重复字符的最长子串(⭐️⭐️)

思路

哈希表记录该字符最近一次出现的位置,left,right 为不重复的左右窗口边界,每次遍历都更新一次最大值。

代码

import java.util.HashMap;

public class LengthOfLongestSubstring {

    public int lengthOfLongestSubstring(String s) {
        if (s == null || s.length() == 0) {
            return 0;
        }
        HashMap<Character, Integer> dic = new HashMap<>(); // 统计字符最后一次出现的索引
        int max = 0;
        int left = 0;
        for (int right = 0; right < s.length(); right++) {
            if (dic.containsKey(s.charAt(right))) {
                left = Math.max(left, dic.get(s.charAt(right)) + 1);
            }
            dic.put(s.charAt(right), right);
            max = Math.max(max, right - left + 1);
        }

        return max;
    }

}

复杂度

  • 时间复杂度: O(N)
  • 空间复杂度: O(N)

1. 两数之和(⭐️⭐️)

思路

遍历的时候使用哈希表记录之前的值和位置,下一步直接查找key中是否存在target - nums[i]这个值,存在则取出target - nums[i]的位置,返回结果。

代码

// key: num[i]位置上的值,value:num[i]位置
public class TwoSum {

    public int[] twoSum(int[] nums, int target) {
        HashMap<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            if (map.containsKey(target - nums[i])) {
                return new int[]{map.get(target - nums[i]), i};
            } else {
                map.put(nums[i], i);
            }
        }
        return new int[]{};
    }

}

复杂度

  • 时间复杂度: O(N)
  • 空间复杂度: O(N)

栈,队列

20. 有效的括号(⭐️⭐️)

思路

代码

public class ValidParentheses {

    public boolean isValid(String string) {
        Stack<Character> left = new Stack<>();
        for (char c : string.toCharArray()) {
            if (c == '(' || c == '{' || c == '[') {
                left.push(c);
            } else {
                if (!left.isEmpty() && rightMatchLeft(c) == left.peek()) {
                    left.pop();
                } else {
                    return false;
                }
            }
        }
        return left.isEmpty();
    }

    // 这里题目只有三种情况,不做其他考虑
    private char rightMatchLeft(char c) {
        if (c == '}') {
            return '{';
        }
        if (c == ')') {
            return '(';
        }
        return '[';
    }

}

复杂度

  • 时间复杂度:O(N)
  • 空间复杂度:O(N)

232. 用栈实现队列(⭐️⭐)

思路

代码

import java.util.Stack;

public class ImplementQueueUsingStacks {
    private Stack<Integer> s1, s2;

    public ImplementQueueUsingStacks() {
        s1 = new Stack<>();
        s2 = new Stack<>();
    }

    public void push(int x) {
        s1.push(x);
    }

    public int pop() {
        peek();
        return s2.pop();
    }

    public int peek() {
        if (s2.isEmpty()) {
            while (!s1.isEmpty()) {
                s2.push(s1.pop());
            }
        }
        return s2.peek();
    }
    
    public boolean empty() {
        return s1.isEmpty() && s2.isEmpty();
    }

}

复杂度

  • 时间复杂度:O(1)
  • 空间复杂度:O(N)

155. 最小栈(⭐️⭐️)

思路

代码

import java.util.Stack;

public class MinStack {
    private Stack<Integer> stack, minStack;
    
    public MinStack() {
        stack = new Stack();
        minStack = new Stack();
        minStack.push(Integer.MIN_VALUE);
    }
    
    public void push(int val) {
        stack.push(val);
        minStack.push(Math.min(minStack.peek(), val));
    }
    
    public void pop() {
        stack.pop();
        minStack.pop();
    }
    
    public int top() {
        return stack.peek();
    }
    
    public int getMin() {
        return minStack.peek();
    }
    
}

复杂度

  • 时间复杂度:O(1)
  • 空间复杂度:O(N)

215. 数组中的第K个最大元素(⭐️⭐️)

思路

堆排序。

代码

// 最大堆
public class FindKthLargest {

    public int findKthLargest(int[] nums, int k) {
        PriorityQueue<Integer> heap = new PriorityQueue<>(
                (o1, o2) -> o2 - o1
        );
        for (int num : nums) {
            heap.offer(num);
        }
        for (int i = 0; i < k - 1; i++) {
            heap.poll();
        }

        return heap.peek();
    }

}

复杂度

  • 时间复杂度:O(N * logN)
  • 空间复杂度:O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值