寒假的时候粗略的刷过一遍,但是仍有一些不太理解,而且忘的差不多了…
在秋招前再刷一遍QAQ
记录一下
动态规划详解:帅地知乎讲解
class CQueue {
Deque<Integer> stack1 = null;
Deque<Integer> stack2 = null;
public CQueue() {
stack1 = new LinkedList<Integer>();
stack2 = new LinkedList<Integer>();
}
public void appendTail(int value) {
stack1.push(value);
}
public int deleteHead() {
if(stack2.isEmpty()){
while(!stack1.isEmpty()){
stack2.push(stack1.pop());
}
}
if(stack2.isEmpty()){ //注意此处的情况:队列为空
return -1;
}else{
return stack2.pop();
}
}
}
/**
* Your CQueue object will be instantiated and called as such:
* CQueue obj = new CQueue();
* obj.appendTail(value);
* int param_2 = obj.deleteHead();
*/
class MinStack {
Deque<Integer> stack1 = null;
Deque<Integer> stack2 = null;
/** initialize your data structure here. */
public MinStack() {
stack1 = new LinkedList<Integer>();
stack2 = new LinkedList<Integer>();
}
public void push(int x) {
stack1.push(x);
if(stack2.isEmpty()||stack2.peek()>=x){ //放前面:判断是否为空;不然stack2.peek()会报错
stack2.push(x);
}
}
public void pop() {
if(stack1.pop().equals(stack2.peek())){
stack2.pop();
}
}
public int top() {
return stack1.peek();
}
public int min() {
return stack2.peek();
}
}
/**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(x);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.min();
*/
/**
辅助栈
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public int[] reversePrint(ListNode head) {
ListNode p = head;
Deque<Integer> stack = new LinkedList<Integer>();
int num=0;
while(p!=null){
stack.push(p.val);
p=p.next;
num++;
}
int[] ans = new int[num];
int i=0;
while(stack.peek()!=null){
ans[i++] = stack.pop();
}
return ans;
}
}
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
ArrayList<Integer>tmp = new ArrayList<Integer>();
public int[] reversePrint(ListNode head) {
recur(head);
int[] ans = new int[tmp.size()];
for(int i=0;i<ans.length;i++){
ans[i] = tmp.get(i);
}
return ans;
}
void recur(ListNode p){
if(p==null)return;
recur(p.next);
tmp.add(p.val);
}
}
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode cur=head,pre=null;
while(cur!=null){
ListNode tmp = cur.next;
cur.next = pre;
pre = cur;
cur = tmp;
}
return pre;
}
}
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode pre = null;
return recur(head,pre);
}
ListNode recur(ListNode head,ListNode pre){
if(head==null)return pre;
ListNode ans = recur(head.next,head);
head.next = pre;
return ans;
}
}
/*
// Definition for a Node.
class Node {
int val;
Node next;
Node random;
public Node(int val) {
this.val = val;
this.next = null;
this.random = null;
}
}
*/
class Solution {
public Node copyRandomList(Node head) {
//哈希表
Node cur = head;
Map<Node,Node> map = new HashMap<>();
//复制结点到新的 存在map中
while(cur!=null){
Node node = new Node(cur.val);
map.put(cur,node);
cur = cur.next;
}
//遍历 构建新的关系
cur = head;
while(cur!=null){
map.get(cur).next = map.get(cur.next);
map.get(cur).random = map.get(cur.random);
cur = cur.next;
}
return map.get(head);
}
}
class Solution {
public String replaceSpace(String s) {
StringBuilder sb = new StringBuilder();
for(char c:s.toCharArray()){
if(c==' '){
sb.append("%20");
}
else sb.append(c);
}
return sb.toString();
}
}
class Solution {
public String reverseLeftWords(String s, int n) {
return s.substring(n, s.length()) + s.substring(0, n);
}
}
class Solution {
public String reverseLeftWords(String s, int n) {
StringBuilder res = new StringBuilder();
for(int i=n;i<s.length();i++){
res.append(s.charAt(i));
}
for(int i=0;i<n;i++){
res.append(s.charAt(i));
}
return res.toString();
}
}
class Solution {
public int findRepeatNumber(int[] nums) {
HashSet<Integer> ans = new HashSet<>();
for(int i:nums){
if(!ans.add(i)){
return i;
}
}
return 0;
}
}
class Solution {
public int findRepeatNumber(int[] nums) {
int i = 0;
while(i < nums.length) {
if(nums[i] == i) {
i++;
continue;
}
if(nums[nums[i]] == nums[i]) return nums[i];
int tmp = nums[i];
nums[i] = nums[tmp];
nums[tmp] = tmp;
}
return -1;
}
}
二分法(一)
l=0,r=nums.length; while(l);l=mid+1,r=mid;
二分法(二)
l=0,r=nums.length-1; while(l<=r);l=mid+1,r=mid-1;
class Solution {
public int search(int[] nums, int target) {
int l=0,r=nums.length,index=0,ans=0;
while(l<r){
int mid = (l+r)/2;
if(nums[mid]==target){
index=mid;
break;
}else if(nums[mid]<target){
l=mid+1;
}else
r=mid;
}
for(int i=index;i<nums.length;i++){
if(nums[i]==target)
ans++;
else{
break;
}
}
for(int i=index-1;i>=0;i--){
if(nums[i]==target)
ans++;
else{
break;
}
}
return ans;
}
}
class Solution {
public int missingNumber(int[] nums) {
int l=0,r=nums.length-1;
while(l<=r){
int mid = (l+r)/2;
if(nums[mid]==mid)l++;
else{
r--;
}
}
return l;
}
}
class Solution {
public int missingNumber(int[] nums) {
int i=0,p=1;
while(i<nums.length-1){
p=i+1;
if(nums[p]-nums[i]!=1)
return nums[p]-1;
else{
i++;
}
}
if(nums[0]==0) return (nums[nums.length-1]+1);
return 0;
}
}
class Solution {
public boolean findNumberIn2DArray(int[][] matrix, int target) {
int i=matrix.length-1,j=0;
while(i>=0&&j<matrix[0].length){
if(target==matrix[i][j])return true;
else if(target>matrix[i][j])j++;
else i--;
}
return false;
}
}
class Solution {
public int minArray(int[] numbers) {
int i=0,j=numbers.length-1;
while(i<j){
int mid = (i+j)/2;
if(numbers[mid]==numbers[j]){
j--;
}else if(numbers[mid]<numbers[j]){
j=mid;
}else i=mid+1;
}
return numbers[i];
}
}
class Solution {
public char firstUniqChar(String s) {
int[] count = new int[26];
char[] c = s.toCharArray();
for(int i=0;i<s.length();i++){
count[(c[i]-'a')]++;
}
for(int i=0;i<s.length();i++){
if(count[c[i]-'a']==1)return c[i];
}
return ' ';
}
}
class Solution {
public char firstUniqChar(String s) {
HashMap<Character,Boolean> map = new HashMap<>();
char[] arr = s.toCharArray();
for(char c:arr){
map.put(c,!map.containsKey(c));
}
for(char c:arr){
if(map.get(c))
return c;
}
return ' ';
}
}
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int[] levelOrder(TreeNode root) {
if(root==null)return new int[0];
Queue<TreeNode> queue = new LinkedList<>(){{add(root);}};
// Queue queue = new LinkedList<>(){{ add(root); }};
ArrayList<Integer> list = new ArrayList<>();
while(!queue.isEmpty()){
TreeNode node = queue.poll();
list.add(node.val);
if(node.left!=null)queue.add(node.left);
if(node.right!=null)queue.add(node.right);
}
int[] ans = new int[list.size()];
for(int i=0;i<list.size();i++){
ans[i] = list.get(i);
}
return ans;
}
}
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
Queue<TreeNode> q = new LinkedList<>();
ArrayList<List<Integer>> list = new ArrayList<>();
if(root!=null)q.add(root);
while(!q.isEmpty()){
List<Integer> t = new ArrayList<>();
for(int i=q.size();i>0;i--){
TreeNode node = q.poll();
t.add(node.val);
if(node.left!=null)q.add(node.left);
if(node.right!=null)q.add(node.right);
}
list.add(t);
}
return list;
}
}
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<TreeNode>();
List<List<Integer>> ans = new ArrayList<List<Integer>>();
if(root!=null)queue.add(root);
while(!queue.isEmpty()){
LinkedList<Integer> list = new LinkedList<>();
for(int i=queue.size();i>0;i--){
TreeNode node = queue.poll();
if(ans.size()%2==0)//是偶数层 从0层开始
list.add(node.val);
else list.addFirst(node.val);
if(node.left!=null)queue.add(node.left);
if(node.right!=null)queue.add(node.right);
}
ans.add(list);
}
return ans;
}
}
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isSubStructure(TreeNode A, TreeNode B) {
if(A==null||B==null)return false;
//遍历A中的每个结点
return isContain(A,B)||isSubStructure(A.left,B)||isSubStructure(A.right,B);
}
public boolean isContain(TreeNode A,TreeNode B){
if(B==null)return true;
if(A==null||A.val!=B.val)return false;
return isContain(A.left,B.left)&&isContain(A.right,B.right);
}
}
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode mirrorTree(TreeNode root) {
if(root==null)return null;
TreeNode tmpleft = mirrorTree(root.right);
TreeNode tmpright = mirrorTree(root.left);
root.left =tmpleft;
root.right =tmpright;
return root;
}
}
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isSymmetric(TreeNode root) {
return root==null?true:isCompare(root.left,root.right);
}
public boolean isCompare(TreeNode l,TreeNode r){
if(l==null&&r==null)return true;
if(l==null||r==null||l.val!=r.val)return false;
return isCompare(l.left,r.right)&&isCompare(l.right,r.left);
}
}
class Solution {
int[] dp = new int[200];
public int fib(int n) {
if(n<2)return n;
int mod = 1000000007;
if(dp[n]!=0)return dp[n];
dp[n] = fib(n-1)+fib(n-2);
dp[n]%=mod;
return dp[n];
}
}
class Solution {
int[] dp = new int[101];
public int fib(int n) {
dp[0]=0;
dp[1]=1;
for(int i=2;i<=n;i++){
dp[i] = dp[i-1]+dp[i-2];
dp[i]%=1000000007;
}
return dp[n];
}
}
class Solution {
int[] dp = new int[105];
public int numWays(int n) {
if(n==0)return 1;
if(n<3)return n;
int mod = 1000000007;
if(dp[n]!=0)return dp[n];
dp[n] = numWays(n-1)+numWays(n-2);
dp[n]%=mod;
return dp[n];
}
}
class Solution {
public int maxProfit(int[] prices) {
//动态规划
//到今天最大的利润值=Math.min(到前一天最大的利润,今天价格-前几天minCost)
//minCost = Math.min(minCost,今天-1天的价格)
if(prices.length==0)return 0;
int cost = prices[0];
int profit = 0;
for(int price:prices){
cost = Math.min(price,cost);
profit = Math.max(profit,price-cost);
}
return profit;
}
}
class Solution {
public int maxProfit(int[] prices) {
int i=0,j=i+1;
int max = 0;
while(j<=prices.length-1){
int p = prices[j]-prices[i];
if(p<0)i++;
else if(p<=max)j++;
else{
max=p;
j++;
}
}
return max;
}
}
class Solution {
public int maxSubArray(int[] nums) {
int[] dp = new int[nums.length];
int max=nums[0];
dp[0] = nums[0];
for(int i=1;i<nums.length;i++){
//简化写法
dp[i] = Math.max(dp[i-1],0)+nums[i];
max = Math.max(max,dp[i]);
}
return max;
}
}
class Solution {
public int maxSubArray(int[] nums) {
int[] dp = new int[nums.length];
int max=nums[0];
dp[0] = nums[0];
for(int i=1;i<nums.length;i++){
if(dp[i-1]>0){
dp[i] = dp[i-1]+nums[i];
if(max<dp[i])max=dp[i];
}else{
dp[i] = nums[i];
if(max<dp[i])max=dp[i];
}
}
return max;
}
}
class Solution {
public int maxValue(int[][] grid) {
int[][] dp = new int[grid.length+1][grid[0].length+1];
for(int i=0;i<grid.length;i++){
for(int j=0;j<grid[0].length;j++){
dp[i+1][j+1] = Math.max(dp[i][j+1],dp[i+1][j])+grid[i][j];
}
}
return dp[grid.length][grid[0].length];
}46
}
class Solution {
public int translateNum(int num) {
//动态规划 判断每次的最后两位->是否能满足有两种->10~25
//dp[i] = dp[i-1]+dp[i-2];
//dp[i] = dp[i-1]
String n = String.valueOf(num);
int[] dp = new int[n.length()+1];
//dp[0] = dp[1] =1;
dp[0] = 1;dp[1] = 1;
for(int i=2;i<=n.length();i++){
String tmp = n.substring(i-2,i);
if(tmp.compareTo("10")>=0&&tmp.compareTo("25")<=0){
dp[i] = dp[i-1]+dp[i-2];
}else{
dp[i] = dp[i-1];
}
}
return dp[n.length()];
}
}
滑动窗口
class Solution {
public int lengthOfLongestSubstring(String s) {
if (s.length()==0) return 0;
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
int max = 0;
int left = 0;
for(int i = 0; i < s.length(); i ++){
if(map.containsKey(s.charAt(i))){
left = Math.max(left,map.get(s.charAt(i)) + 1);
}
map.put(s.charAt(i),i);
max = Math.max(max,i-left+1);
}
return max;
}
}
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode deleteNode(ListNode head, int val) {
ListNode p=head,q=head.next;
-
if(p.val==val)return q;
while(q!=null){
if(q.val==val){
p.next = q.next;
return head;
}
p=q;
q=q.next;
}
return head;
}
}
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
//快慢指针
ListNode s=head,f=head;
for(int i=0;i<k;i++) f=f.next;
while(f!=null){
s=s.next;
f=f.next;
}
return s;
}
}
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode l = new ListNode(0);
ListNode cur = l;
while(l1!=null&&l2!=null){
if(l1.val<l2.val){
cur.next = l1;
l1 = l1.next;
}else{
cur.next = l2;
l2 = l2.next;
}
cur = cur.next;
}
if(l1!=null) cur.next = l1;
if(l2!=null) cur.next = l2;
return l.next;
}
}
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode p1=headA,p2=headB;
while(p1!=p2){
p1 = p1!=null?p1.next:headB;
p2 = p2!=null?p2.next:headA;
}
return p1;
}
}
class Solution {
public int[] exchange(int[] nums) {
int p=0,q=nums.length-1;
while(p<q){
while(nums[p]%2!=0&&p<q)p++;//找偶数 并且防止越界
if(nums[q]%2!=0){//是奇数
int tmp = nums[q];
nums[q] = nums[p];
nums[p] = tmp;
p++;
}
q--;
}
return nums;
}
}
class Solution {
public int[] twoSum(int[] nums, int target) {
int i = 0, j = nums.length - 1;
while(i < j) {
int s = nums[i] + nums[j];
if(s < target) i++;
else if(s > target) j--;
else return new int[] { nums[i], nums[j] };
}
return new int[0];
}
}
class Solution {
public String reverseWords(String s) {
s = s.trim();
StringBuilder sb = new StringBuilder();
int i=s.length()-1,j=i;
while(i>=0){
while(i>=0&&s.charAt(i)!=' ')i--;//找到下一个空格,单词头
sb.append(s.substring(i+1,j+1)+' ');
while(i>=0&&s.charAt(i)==' ')i--;//跳过空格,找到下一个单词尾
j=i;
}
return sb.toString().trim();
}
}
class Solution {
public boolean exist(char[][] board, String word) {
char[] b = word.toCharArray();
for(int i=0;i<board.length;i++){
for(int j=0;j<board[0].length;j++){
if(dfs(board,b,i,j,0)==true)
return true;
}
}
return false;
}
public boolean dfs(char[][] board,char[] b,int i,int j,int k){
if(i>=board.length||i<0||j>=board[0].length||j<0||board[i][j]!=b[k])return false;
if(k==b.length-1)return true;//全部通过
board[i][j] = '\0'; //防止重复
boolean res = dfs(board,b,i+1,j,k+1)||dfs(board,b,i-1,j,k+1)||dfs(board,b,i,j-1,k+1)||dfs(board,b,i,j+1,k+1);
board[i][j] = b[k]; //恢复
return res;
}
}
class Solution {
public int movingCount(int m, int n, int k) {
boolean visited[][] = new boolean[m][n];
return dfs(visited,0,0,m,n,k);
}
public int dfs(boolean[][] visited,int i,int j,int m,int n,int k){
if(i>=m||j>=n||visited[i][j]||cal(i)+cal(j)>k)return 0;
visited[i][j] = true;
return 1+dfs(visited,i+1,j,m,n,k)+dfs(visited,i,j+1,m,n,k);
}
public int cal(int x){
int sum =0;
while(x>0){
sum+=x%10;
x/=10;
}
return sum;
}
}
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
LinkedList<Integer> path = new LinkedList<>();
LinkedList<List<Integer>> res = new LinkedList<>();
int sum=0;
public List<List<Integer>> pathSum(TreeNode root, int target) {
if(root!=null){
dfs(root,target,sum);
}
return res;
}
public void dfs(TreeNode root,int target,int sum){
sum+=root.val;
path.add(root.val);
if(root.left!=null)dfs(root.left,target,sum);
if(root.right!=null)dfs(root.right,target,sum);
//判断是否满足
if(sum==target&&root.left==null&&root.right==null)
res.add(new LinkedList(path));
//回溯清空
path.removeLast();
}
}
```java
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
LinkedList<List<Integer>> res = new LinkedList<>();
LinkedList<Integer> p = new LinkedList<>();
public List<List<Integer>> pathSum(TreeNode root, int target) {
dfs(root,target);
return res;
}
public void dfs(TreeNode root ,int target){
if(root==null)return;
p.add(root.val);
target-=root.val;
if(target==0&&root.left==null&&root.right==null)
res.add(new LinkedList(p));//链表
dfs(root.left,target);
dfs(root.right,target);
p.removeLast();//回溯需要清除
}
}
class Solution {
Node pre, head;
public Node treeToDoublyList(Node root) {
if(root == null) return null;
dfs(root);
head.left = pre;
pre.right = head;
return head;
}
void dfs(Node cur) {
if(cur == null) return;
dfs(cur.left);
if(pre != null) pre.right = cur;
else head = cur;
cur.left = pre;
pre = cur;
dfs(cur.right);
}
}
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
int sum=0,res=0;
public int kthLargest(TreeNode root, int k) {
//二叉搜索树 中序遍历 倒序:右 根 左
dfs(root,k);
return res;
}
public void dfs(TreeNode root,int k){
if(root==null)return;
dfs(root.right,k);
if(++sum==k){
res=root.val;
return;
}
dfs(root.left,k);
}
}
//快排模板:sort patition swap 从小到大排序
void sort(int[] nums,int start,int end){
if(start>=end)return;
int p = patition(nums,start,end);
sort(nums,start,p-1);
sort(nums,p+1,end);
}
int partition(int[] nums,int start,int end){
int p = end; //取的最后一个值
int i = start;
for(int j=start;j<end;j++){
if(nums[j]<nums[p]){ //小到大排序
swap(nums,i,j);
i++;
}
}
swap(nums,i,p); //找到标志位了
return i;
}
void swap(int[] nums,int a,int b ){
int temp = nums[a];
nums[a] = nums[b];
nums[b] = temp;
}
class Solution {
public String minNumber(int[] nums) {
String res = "";
sort(nums,0,nums.length-1);
for(int i:nums){
res = res+i+"";
}
return res;
}
void sort(int[] nums,int start,int end){
if(start>=end)return;
int p = patition(nums,start,end);
sort(nums,start,p-1);
sort(nums,p+1,end);
}
int patition(int[] nums,int start,int end){
int p = end;
int i = start;
String pv = String.valueOf(nums[p]);
for(int j=start;j<end;j++){
String t = String.valueOf(nums[j]);
if((t+pv).compareTo(pv+t)<0){
swap(nums,i,j);
i++;
}
}
swap(nums,i,p);
return i;
}
void swap(int[] nums,int a,int b){
int temp = nums[a];
nums[a] = nums[b];
nums[b] = temp;
}
}
class Solution {
public boolean isStraight(int[] nums) {
HashSet<Integer> set = new HashSet<>();
int min=14,max=0;
for(int i:nums){
if(i!=0){
if(set.contains(i))return false;
set.add(i);
min = min<i?min:i;
max = max>i?max:i;
}
}
return max-min<5?true:false;
}
}
class Solution {
//看清题意:大小王可以充当任意牌 意味max-min<5且无重复就行 大小王不用管
public boolean isStraight(int[] nums) {
Arrays.sort(nums);
int min=nums[4],max=nums[4];
for(int i=0;i<4;i++){
if(nums[i]==0)continue;
if(nums[i]==nums[i+1])return false;
if(nums[i]<min)min=nums[i];
}
if(max-min>=5)return false;
return true;
}
}
class Solution {
public int[] getLeastNumbers(int[] arr, int k) {
Arrays.sort(arr);
int[] res = new int[k];
for(int i=0;i<k;i++){
res[i] = arr[i];
}
return res;
}
}
class MedianFinder {
PriorityQueue<Integer>big;
PriorityQueue<Integer>small;
/** initialize your data structure here. */
public MedianFinder() {
big = new PriorityQueue<>((n1,n2)->n2-n1);
small = new PriorityQueue<>();
}
public void addNum(int num) {
big.add(num);
small.add(big.poll());
if(small.size()-big.size()>1)
big.add(small.poll());
}
public double findMedian() {
if(small.size()>big.size())return small.peek();
return (double)(small.peek()+big.peek())/2;
}
}
/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder obj = new MedianFinder();
* obj.addNum(num);
* double param_2 = obj.findMedian();
*/
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int maxDepth(TreeNode root) {
if(root==null)return 0;
return 1+Math.max(maxDepth(root.left),maxDepth(root.right));
}
}
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isBalanced(TreeNode root) {
if(root==null)return true;
return (Math.abs(maxD(root.left)-maxD(root.right))<=1)&&isBalanced(root.left)&&isBalanced(root.right);
}
public int maxD(TreeNode root){
if(root==null)return 0;
return Math.max(maxD(root.left),maxD(root.right))+1;
}
}
class Solution {
public int sumNums(int n) {
boolean x = (n>1)&&((n+=sumNums(n-1))>0);
return n;
}
}
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
//二叉搜索树性质 左小右大
//作差相乘 异侧 符号不同 <=0
if((root.val-q.val)*(root.val-p.val)<=0)return root;
return lowestCommonAncestor(root.val>q.val?root.left:root.right,p,q);
}
}
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
//同样看两侧,需递归找到底p q,找不到返回null
//出口:先找到底
if(root==null||root==p||root==q)return root;
//先序 递归 找底
TreeNode left = lowestCommonAncestor(root.left,p,q);
TreeNode right = lowestCommonAncestor(root.right,p,q);
//判断 root的左右都不为空 就是root
if(left==null)return right;
if(right==null)return left;
return root;
}
}
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
int[] pre;
//存放先序节点在中序中的位置 key:先序节点的值 Value:在中序数值中的下标
HashMap<Integer,Integer> map = new HashMap<>();
public TreeNode buildTree(int[] preorder, int[] inorder) {
pre = preorder;
//初始化
int index = 0;
for(int i:inorder){
map.put(i,index++);
}
return recur(0,0,inorder.length-1);
}
public TreeNode recur(int root,int left,int right){
//出口
if(left>right)return null;
TreeNode node = new TreeNode(pre[root]);
//根节点在中序遍历的位置i
int i = map.get(pre[root]);
//在先序遍历root的下一个就是左节点 在中序遍历中左树截止到i
node.left = recur(root+1,left,i-1);
//在先序遍历中root后跟左树结束才右节点root+(i-left)+1 在中序遍历中i的后边是右子树
//i-left是左树的长度
node.right = recur(root+(i-left)+1,i+1,right);
return node;
}
}
class Solution {
public double myPow(double x, int n) {
if(x==0)return 0;
double res=1.0;
long b = n;
//分数
if(b<0){
x=1/x;
b=-b;
}
while(b>0){
//从二进制角度看 是1才乘上权重
if((b&1)==1)
res*=x;
//得到每个位置的值
x*=x;
b>>=1;
}
return res;
}
}
class Solution {
public boolean verifyPostorder(int[] postorder) {
return recur(postorder,0,postorder.length-1);
}
public boolean recur(int[] postorder,int left,int right){
//出口
if(left>=right)return true;
int p=left;
//找到左子树的头m-1
while(postorder[p]<postorder[right])p++;
int m = p;
//找到右子树的头p-1
while(postorder[p]>postorder[right])p++;
//递归遍历 左子树 右子树 扔掉根节点
return p==right && recur(postorder,left,m-1)&&recur(postorder,m,right-1);
}
}
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int res=0;
while(n!=0){
if((n&1)==1)res++;
n>>>=1;
}
return res;
}
}
class Solution {
//用递归代替加法:(int a,int b)相当于 a+b
public int add(int a, int b) {
//出口:进位和=0
while(b!=0){
int c = (a&b)<<1; //进位和
a = a ^ b; //非进位和
b = c;
}
return a;
}
}
//hashmap
class Solution {
public int[] singleNumbers(int[] nums) {
HashMap<Integer,Integer> map = new HashMap<>();
for(int i:nums){
map.put(i,map.getOrDefault(i,0)+1);
}
int[] res = new int[2];
int n=0;
for(int i:nums){
if(map.get(i)==1)
res[n++]=i;
}
return res;
}
}
class Solution {
public int singleNumber(int[] nums) {
HashMap<Integer,Integer> map = new HashMap<>();
for(int i:nums){
map.put(i,map.getOrDefault(i,0)+1);
}
for(int i:nums){
if(map.get(i)==1)return i;
}
return 0;
}
}
class Solution {
public int majorityElement(int[] nums) {
int tmp = 0,count=0;
for(int i:nums){
if(count==0){
tmp = i;
count++;
}else if(i!=tmp){
count--;
}else if(i==tmp){
count++;
}
}
return tmp;
}
}
class Solution {
public int[] constructArr(int[] a) {
if(a.length==0)return new int[0];
int[] b = new int[a.length];
//迭代:左面 右面
b[0] = 1;
for(int i=0;i<a.length-1;i++){
b[i+1] = b[i]*a[i];
}
int tmp=1;
for(int i=a.length-1;i>0;i--){
tmp*=a[i];
b[i-1]*=tmp;
}
return b;
}
}
class Solution {
public int cuttingRope(int n) {
//dp[i]:长度为i的绳子 最大乘积为?
int[] dp = new int[n+1];
//长度为0 1都不能再分
dp[0] = dp[1] = 0;
for(int i=2;i<=n;i++){//长度为i的绳子
for(int j=1;j<i;j++){//第一段长度为j,不能超过i
//内层:第一段分成j 剩下的继续分dp[i-j] 不分(i-j)
dp[i] = Math.max( Math.max(j*dp[i-j],j*(i-j)) ,dp[i]);
}
}
return dp[n];
}
}
class Solution {
public int[][] findContinuousSequence(int target) {
//左闭右开
int i=1,j=1;
int sum=0;
List<int[]>res = new ArrayList<>();
while(i<target){
if(sum<target){
sum+=j;
j++;
}else if(sum>target){
sum-=i;
i++;
}else{
int[] tmp = new int[j-i];
int t=0;
for(int k=i;k<j;k++){
tmp[t++] = k;
}
res.add(tmp);
//优化
sum-=(i+i+1);
i+=2;
}
}
return res.toArray(new int[res.size()][]);
}
}
class Solution {
public int lastRemaining(int n, int m) {
int res = 0;//胜利者最后角标为0
for(int i=2;i<=n;i++){//每次推导上一轮 res对应角标 i代表存活者个数
res = (res+m)%i;
}
return res;
}
}
class Solution {
public int[] spiralOrder(int[][] matrix) {
if(matrix.length==0)return new int[0];
int r = matrix[0].length-1,bottom = matrix.length-1;
int[] res = new int[(r+1)*(bottom+1)];
int sum=0,top=0,l=0;
while(true){
for(int t=l;t<=r;t++)res[sum++] = matrix[top][t]; //左到右
//换行
if(++top>bottom)break;
for(int t=top;t<=bottom;t++)res[sum++] = matrix[t][r]; //上到下
//换列
if(l>--r)break;
for(int t=r;t>=l;t--)res[sum++] = matrix[bottom][t];//从右到左
//换行
if(top>--bottom)break;
for(int t=bottom;t>=top;t--)res[sum++] = matrix[t][l];//从下到上
if(++l>r)break;
}
return res;
}
}
class Solution {
public boolean validateStackSequences(int[] pushed, int[] popped) {
Deque<Integer> stack = new LinkedList<>();
int index=0;
for(int i:pushed){
stack.push(i);
while(!stack.isEmpty()&&stack.peek()==popped[index]){
stack.pop();
index++;
}
}
return stack.isEmpty();
}
}
class Solution {
public int nthUglyNumber(int n) {
int[] dp = new int[n];
dp[0]=1;
int a=0,b=0,c=0;
for(int i=1;i<n;i++){
int tmp = Math.min(Math.min(dp[a]*2,dp[b]*3),dp[c]*5);
if(tmp==dp[a]*2)a++;
if(tmp==dp[b]*3)b++;
if(tmp==dp[c]*5)c++;
dp[i] = tmp;
}
return dp[n-1];
}
}