哈希表
哈希表这种 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)