设计题
1 LRU缓存
解题思路
package 力扣.设计题;
import codeTop.递归.广度优先.LC827;
import java.util.*;
public class LC164 {
private int cap;
private Map<Integer,Integer> map=new LinkedHashMap<>();
public LC164(int capacity) {
this.cap=capacity;
}
public int get(int key) {
if(map.keySet().contains(key)){
int value=map.get(key);
map.remove(key);
//保证每次查询之后,都在末尾
map.put(key,value);
return value;
}
return -1;
}
public void put(int key, int value) {
if(map.keySet().contains(key)){
map.remove(key);
}else if(map.size()==cap){
//这一句是取出最久未访问的数值
Iterator<Map.Entry<Integer,Integer>> iterator=map.entrySet().iterator();
iterator.next();
iterator.remove();
}
map.put(key,value);
}
public static void main(String[] args) {
}
}
排序
1 手撕快速排序
原地哈希
1消失的2个数字
class Solution {
public int[] missingTwo(int[] nums) {
int n = nums.length;
if (n == 0) return new int[0];
int[] result = new int[2];
// 原地哈希
for (int i = 0;i < n;++i) {
int idx = Math.abs(nums[i]) - 1;
if (idx < n) nums[idx] = -nums[idx];
}
int p = 0;
// 找那些没有变为负数的下标(没有出现的值)
for (int i = 0;i < n;++i) {
if (nums[i] > 0) {
nums[i] = -nums[i];
result[p++] = i + 1;
}
}
if (p == 2) return result;
// 到达这里说明,1~n的数字都出现过了,缺失的数字在[n+1,N]之间
int min = n+1;
// 找到[n+1,N]之间缺失的数字的最小值
for (int v:nums) {
if (Math.abs(v) == min) ++min;
}
while (p < 2) {
result[p++] = min++;
}
return result;
}
}
括号匹配
使括号有效的最小添加
贪心做法通过每次消除()片段可以得到最优解,但是这种复杂度回答道O(n^2)显然不是最优的解决方法。
class Solution {
public int minAddToMakeValid(String s) {
while (s.contains("()")){
s=s.replace("()","");
}
return s.length();
}
}
在这里我们借用栈的思路
class Solution {
public int minAddToMakeValid(String s) {
//每找到一个右括号就必须使用一个左括号来进行匹配,没有就添加
Stack<Character> stack=new Stack<>();
int ans=0;
for(int i=0;i<s.length();i++){
if(s.charAt(i)=='('){
stack.push(s.charAt(i));
}else {
if(!stack.isEmpty()){
stack.pop();
}else {
ans++;
}
}
}
//当右括号不足的时候,选择补全左括号
while (!stack.isEmpty()){
ans++;
stack.pop();
}
return ans;
}
}