- 128. 最长连续序列">128. 最长连续序列
- 136. 只出现一次的数字">136. 只出现一次的数字
- 146. LRU 缓存">146. LRU 缓存
- 148. 排序链表">148. 排序链表
- 152. 乘积最大子数组">152. 乘积最大子数组
- 169. 多数元素">169. 多数元素
- 207. 课程表(拓扑排序)">207. 课程表(拓扑排序)
- 208. 实现 Trie (前缀树)">208. 实现 Trie (前缀树)
- 215. 数组中的第K个最大元素">215. 数组中的第K个最大元素
- 221. 最大正方形">221. 最大正方形
- 234. 回文链表">234. 回文链表
- 238. 除自身以外数组的乘积">238. 除自身以外数组的乘积
- 239. 滑动窗口最大值">239. 滑动窗口最大值
- 240. 搜索二维矩阵 II">240. 搜索二维矩阵 II
- 287. 寻找重复数(二分法)">287. 寻找重复数(二分法)
- 297. 二叉树的序列化与反序列化">297. 二叉树的序列化与反序列化
- 300. 最长递增子序列*">300. 最长递增子序列*
- 301. 删除无效的括号">301. 删除无效的括号
- 338. 比特位计数">338. 比特位计数
- 347. 前 K 个高频元素">347. 前 K 个高频元素
128. 最长连续序列
int res=0;Set<Integer> set = new HashSet<>();for(int i=0;i<nums.length;i++){set.add(nums[i]);}for (Integer integer : set) {int cur=integer;if(!set.contains(cur-1)){while (set.contains(cur)){cur+=1;}res=Math.max(res,cur-integer);}}return res;
136. 只出现一次的数字
//异或运算是相同为假,不同为真。比如4^1就是// 0 1 0 0// 0 0 0 1// 0 1 0 1 =5int res=0;for(int i=0;i<nums.length;i++){res^=nums[i];}return res;
146. LRU 缓存
class LRUCache {private LinkedHashMap<Integer,Integer>map=new LinkedHashMap<>();private int cap;public LRUCache(int capacity) {this.cap=capacity;}public int get(int key) {if(map.containsKey(key)){int value=map.get(key);flushRecent(key,value);return value;}else{return -1;}}public void put(int key, int value) {if(map.containsKey(key)){flushRecent(key,value);}else{map.put(key,value);if(map.size()>cap){int oldKey = map.keySet().iterator().next();map.remove(oldKey);}}}private void flushRecent(int key,int value){map.remove(key);map.put(key,value);}}
解法二:自定义链表
import java.util.HashMap;import java.util.Map;class LRUCache {private static class ListNode{ListNode pre;ListNode next;int key;int value;public ListNode(int key, int value) {this.key = key;this.value = value;}}private static class NodeLinkedList{ListNode head=null;ListNode tail=null;public void addNode(ListNode node){if(head==null){head=node;tail=node;}else{tail.next=node;node.pre=tail;tail=node;}}public void adjustToTail(ListNode node){if(node==tail){return;}else if(head==node){ListNode next=node.next;node.next=null;next.pre=null;head=next;}else{ListNode pre=node.pre;ListNode next=node.next;node.pre=null;node.next=null;pre.next=next;next.pre=pre;}tail.next=node;node.pre=tail;tail=node;}public ListNode deleteHead(){if(head==null){return null;}else if(tail==head){head=null;tail=null;return tail;}else{ListNode hd=head;ListNode next=head.next;head.next=null;next.pre=null;head=next;return hd;}}}private int cap;private NodeLinkedList list=new NodeLinkedList();private Map<Integer,ListNode> map=new HashMap<>();public LRUCache(int capacity) {this.cap=capacity;}public int get(int key) {if(!map.containsKey(key)){return -1;}else{ListNode node = map.get(key);list.adjustToTail(node);return node.value;}}public void put(int key, int value) {if(map.containsKey(key)){ListNode node = map.get(key);node.value=value;map.put(key,node);list.adjustToTail(node);}else{ListNode node = new ListNode(key, value);map.put(key,node);list.addNode(node);if(map.size()>cap){ListNode node1 = list.deleteHead();map.remove(node1.key);}}}}
148. 排序链表
public ListNode sortList(ListNode head) {if(head==null||head.next==null){return head;}ListNode mid = findMid(head);ListNode midRight=mid.next;mid.next=null;ListNode left = sortList(head);ListNode right = sortList(midRight);return mergeNode(left,right);}private ListNode findMid(ListNode head){if(head==null||head.next==null){return head;}ListNode fast=head;ListNode slow=head;while (fast.next!=null&&fast.next.next!=null){fast=fast.next.next;slow=slow.next;}return slow;}private ListNode mergeNode(ListNode node1,ListNode node2){ListNode virtualNode = new ListNode(Integer.MIN_VALUE);ListNode temp=virtualNode;while (node1!=null&&node2!=null){if(node1.val<=node2.val){temp.next=node1;node1=node1.next;}else{temp.next=node2;node2=node2.next;}temp=temp.next;}if(node1==null){temp.next=node2;}else{temp.next=node1;}return virtualNode.next;}
152. 乘积最大子数组
int[]maxDp=new int[nums.length];int[]minDp=new int[nums.length];maxDp[0]=nums[0];minDp[0]=nums[0];int res=nums[0];for(int i=1;i<nums.length;i++){maxDp[i]=Math.max(nums[i],Math.max(maxDp[i-1]*nums[i],minDp[i-1]*nums[i]));minDp[i]=Math.min(nums[i],Math.min(maxDp[i-1]*nums[i],minDp[i-1]*nums[i]));res=Math.max(res,maxDp[i]);}return res;
169. 多数元素
int voter=nums[0];int voteCount=0;for(int i=1;i<nums.length;i++){if(nums[i]==voter){voteCount++;}else if(nums[i]!=voter&&voteCount>0){voteCount--;}else{voter=nums[i];voteCount=0;}}return voter;
207. 课程表(拓扑排序)

Map<Integer, Integer> map = new HashMap<>();//用map来保存每个课程的入度。for(int i=0;i<numCourses;i++){map.put(i,0);}//用map集合来保存先决关系,比如先完成0才能完成1、2。 0->1、2Map<Integer, List<Integer>>path=new HashMap<>();for (int[] prerequisite : prerequisites) {int cur=prerequisite[1];int next=prerequisite[0];map.put(next,map.getOrDefault(next,0)+1);if(!path.containsKey(cur)){path.put(cur,new ArrayList<>());}path.get(cur).add(next);}//用queue来取出path中的元素,让入度-1Deque<Integer>queue=new LinkedList<>();for (Integer integer : map.keySet()) {if(map.get(integer)==0){queue.addLast(integer);}}while (!queue.isEmpty()){int cur = queue.pollFirst();if(!path.containsKey(cur)){continue;}for (Integer integer : path.get(cur)) {map.put(integer,map.getOrDefault(integer,0)-1);if(map.get(integer)==0){queue.addLast(integer);}}}for (Integer integer : map.keySet()) {if(map.get(integer)!=0){return false;}}return true;
208. 实现 Trie (前缀树)
class Trie {//前缀树根节点不保存数据,每个节点都有26个字符数组,在word末尾设置boolean标志位private TrieNode root=new TrieNode();class TrieNode{boolean end;TrieNode[]tns=new TrieNode[26];}public Trie() {}public void insert(String word) {TrieNode temp=root;for(int i=0;i<word.length();i++){int location=word.charAt(i)-'a';if(temp.tns[location]==null){temp.tns[location]=new TrieNode();}temp=temp.tns[location];}temp.end=true;}public boolean search(String word) {TrieNode temp=root;for(int i=0;i<word.length();i++){int location=word.charAt(i)-'a';if(temp.tns[location]==null){return false;}else{temp=temp.tns[location];}}return temp.end;}public boolean startsWith(String prefix) {TrieNode temp=root;for(int i=0;i<prefix.length();i++){int location=prefix.charAt(i)-'a';if(temp.tns[location]==null){return false;}else{temp=temp.tns[location];}}return true;}}
215. 数组中的第K个最大元素
PriorityQueue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return o2-o1;}});int res=0;for(int i=0;i<nums.length;i++){queue.add(nums[i]);}while (k>0){res=queue.poll();k--;}return res;
221. 最大正方形

int[][]dp=new int[matrix.length][matrix[0].length];int res=0;for(int i=0;i<matrix.length;i++){for(int j=0;j<matrix[0].length;j++){if(matrix[i][j]=='1'){dp[i][j]=1;res=Math.max(res,dp[i][j]);}}}for(int i=1;i<dp.length;i++){for(int j=1;j<dp[0].length;j++){if(dp[i][j]==0){continue;}else{if(dp[i-1][j]>0&&dp[i][j-1]>0&&dp[i-1][j-1]>0){dp[i][j]=Math.min(dp[i-1][j],Math.min(dp[i][j-1],dp[i-1][j-1]))+1;res=Math.max(res,dp[i][j]);}}}}return res*res;
234. 回文链表
//先寻找链表中间节点ListNode fast=head;ListNode slow=head;while (fast.next!=null&&fast.next.next!=null){fast=fast.next.next;slow=slow.next;}//如果fast.next=null说明是奇数个节点,否则是偶数个节点if(fast.next==null){ListNode last=slow.next;//反转前半部分的链表ListNode pre=null;ListNode temp=head;while (temp!=slow){ListNode next=temp.next;temp.next=pre;pre=temp;temp=next;}//执行判断的逻辑while (pre!=null&&last!=null){if(pre.val!=last.val){return false;}pre=pre.next;last=last.next;}return true;//如果是偶数个节点的情况}else{ListNode last=slow.next;//反转前半部分的链表ListNode pre=null;ListNode temp=head;while (temp!=last){ListNode next=temp.next;temp.next=pre;pre=temp;temp=next;}//执行判断的逻辑while (pre!=null&&last!=null){if(pre.val!=last.val){return false;}pre=pre.next;last=last.next;}return true;
238. 除自身以外数组的乘积
//可以定义两个dp数组,分别保存从左边相乘的数和从右边相乘的数int[] leftDp=new int[nums.length];int[] rightDp=new int[nums.length];int[] res=new int[nums.length];leftDp[0]=nums[0];rightDp[rightDp.length-1]=nums[nums.length-1];for(int i=1;i<leftDp.length;i++){leftDp[i]=nums[i]*leftDp[i-1];}for(int i=rightDp.length-2;i>=0;i--){rightDp[i]=nums[i]*rightDp[i+1];}res[0]=rightDp[1];res[res.length-1]=leftDp[leftDp.length-2];for(int i=1;i<res.length-1;i++){res[i]=leftDp[i-1]*rightDp[i+1];}return res;
239. 滑动窗口最大值
int[]res=new int[nums.length-k+1];Deque<Integer>queue=new LinkedList<>();int index=0;for(int i=0;i<nums.length;i++){//头(清除头部元素)if(!queue.isEmpty()&&queue.peekFirst()==i-k){queue.pollFirst();}//尾(维持一个单调递增的队列)while (!queue.isEmpty()&&nums[i]>=nums[queue.peekLast()]){queue.pollLast();}//尾queue.addLast(i);//头if(i>=k-1){res[index++]=nums[queue.peekFirst()];}}return res;
240. 搜索二维矩阵 II
//从矩阵的左下角入手开始找int row=matrix.length-1;int col=0;while (row>=0&&row<=matrix.length-1&&col>=0&&col<=matrix[0].length-1){if(target==matrix[row][col]){return true;}else if(target>matrix[row][col]){col++;}else{row--;}}return false;
287. 寻找重复数(二分法)
int left=1;int right=nums.length-1;while (left<=right){int count=0;int mid=(left+right)/2;for(int i=0;i<nums.length;i++){if(nums[i]<=mid){count++;}}if(count<=mid){left=mid+1;}else{right=mid-1;}}return left;
297. 二叉树的序列化与反序列化
public class Codec {static class TreeNode{int val;TreeNode left;TreeNode right;public TreeNode(int value) {this.val = value;}public TreeNode() {}public TreeNode(int value,TreeNode left,TreeNode right) {this.val = value;this.left = left;this.right = right;}}// Encodes a tree to a single string.public String serialize(TreeNode root) {if(root==null){return null;}StringBuilder builder = new StringBuilder();Deque<TreeNode>queue=new LinkedList<>();queue.addLast(root);while (!queue.isEmpty()){TreeNode node = queue.pollFirst();if(node!=null) {builder.append(node.val).append(",");}else{builder.append("null").append(",");continue;}queue.addLast(node.left);queue.addLast(node.right);}return builder.toString().substring(0,builder.length()-1);}// Decodes your encoded data to tree.public TreeNode deserialize(String data) {if(data.equals("null")||data.length()==0){return null;}String[] split = data.split(",");int index=1;Deque<TreeNode>queue=new LinkedList<>();TreeNode root = new TreeNode(Integer.parseInt(split[0]));queue.addLast(root);while (!queue.isEmpty()){TreeNode node = queue.pollFirst();if(!split[index].equals("null")){TreeNode left = new TreeNode(Integer.parseInt(split[index]));node.left=left;queue.addLast(left);}index++;if(!split[index].equals("null")){TreeNode right = new TreeNode(Integer.parseInt(split[index]));node.right=right;queue.addLast(right);}index++;}return root;}}
300. 最长递增子序列*
int[]dp=new int[nums.length];Arrays.fill(dp,1);int res=1;for(int i=1;i<nums.length;i++){for(int j=0;j<i;j++){if(nums[i]>nums[j]){dp[i]=Math.max(dp[j]+1,dp[i]);res=Math.max(res,dp[i]);}}}return res;
301. 删除无效的括号
class Solution {private StringBuilder builder=new StringBuilder();private Set<String> set=new HashSet<>();public List<String> removeInvalidParentheses(String s) {int leftCount=0;int rightCount=0;//这里的逻辑是判断看需要删除多少个左括号、右括号for(int i=0;i<s.length();i++){if(s.charAt(i)=='('){leftCount++;}else if(s.charAt(i)==')'){if(leftCount>0){leftCount--;}else{rightCount++;}}}backTrack(0,s,leftCount,rightCount);return new ArrayList<>(set);}private void backTrack(int index,String s,int left,int right){if(index==s.length()){if(left==0&&right==0&&check(builder)){set.add(builder.toString());}return;}char c = s.charAt(index);if(c=='('){builder.append(c);backTrack(index+1,s,left,right);builder.deleteCharAt(builder.length()-1);if(left>0){backTrack(index+1,s,left-1,right);}}else if(c==')'){builder.append(c);backTrack(index+1,s,left,right);builder.deleteCharAt(builder.length()-1);if(right>0){backTrack(index+1,s,left,right-1);}}else{builder.append(c);backTrack(index+1,s,left,right);builder.deleteCharAt(builder.length()-1);}}private boolean check(StringBuilder builder){int left=0;int right=0;for(int i=0;i<builder.length();i++){if(builder.charAt(i)=='('){left++;}else if(builder.charAt(i)==')'){if(left==0){return false;}else{left--;}}}return left==0;}}
338. 比特位计数
int[]dp=new int[n+1];dp[0]=0;for(int i=n;i>=1;i--){int oneCount=0;int temp=i;while (temp!=0){temp&=temp-1;oneCount++;}dp[i]=oneCount;}return dp;
347. 前 K 个高频元素
//大顶堆+哈希表int[]dp=new int[k];Map<Integer,Integer> map=new HashMap<>();for(int i=0;i<nums.length;i++){map.put(nums[i],map.getOrDefault(nums[i],0)+1);}PriorityQueue<Map.Entry<Integer,Integer>>queue=new PriorityQueue<>(new Comparator<Map.Entry<Integer, Integer>>() {@Overridepublic int compare(Map.Entry<Integer, Integer> o1, Map.Entry<Integer, Integer> o2) {return o2.getValue()-o1.getValue();}});for (Map.Entry<Integer, Integer> integerIntegerEntry : map.entrySet()) {queue.add(integerIntegerEntry);}for(int i=0;i<k;i++){dp[i]=queue.poll().getKey();}return dp;
