提交 4ca0257b 编写于 作者: L liu13

20190715

上级 abfdac66
......@@ -23,7 +23,7 @@ public class lc102 {
if(root==null)
return res;
qu.add(root);
while(!qu.isEmpty()){
while(!qu.isEmpty()){ //两个while
int size = qu.size();
List<Integer> temp = new ArrayList<>();
while(size>0){
......
......@@ -20,20 +20,20 @@ public class lc113 {
}
}
public List<List<Integer>> pathSum(TreeNode root, int sum) {
List<List<Integer>> res = new ArrayList<>();
helper(res, root, sum, 0, new ArrayList<>());
List<List<Integer>> res = new ArrayList();
helper(res, new ArrayList(), root, sum);
return res;
}
public void helper(List<List<Integer>> res, TreeNode root, int sum, int curr, List<Integer> curr_ls) {
public void helper(List<List<Integer>> res, List<Integer> cur, TreeNode root, int sum){
if(root==null) return;
curr_ls.add(root.val);
if(curr+root.val==sum && root.left==null && root.right==null) { //到叶子节点
res.add(new ArrayList<>(curr_ls));
curr_ls.remove(curr_ls.size()-1);
return;
cur.add(root.val);
if(root.left==null&&root.right==null&&root.val==sum){ //到叶子节点
res.add(new ArrayList(cur));
}else{
helper(res, cur, root.left, sum-root.val);
helper(res, cur, root.right, sum-root.val);
}
helper(res, root.left, sum, curr+root.val, curr_ls);
helper(res, root.right, sum, curr+root.val, curr_ls);
curr_ls.remove(curr_ls.size()-1);
cur.remove(cur.size()-1);
return;
}
}
package code;
/*
* 122. Best Time to Buy and Sell Stock III
* 123. Best Time to Buy and Sell Stock III
* 题意:买卖股票最大利润,只能买卖2次
* 难度:Hard
* 分类:Array, Dynamic Programming
......
......@@ -10,6 +10,7 @@ import java.util.List;
* 思路:典型回溯法,注意向res添加内容时要重新new一下
* Tips: lc5, lc9, lc125, lc131, lc234, lc647
* lc39
* lc132
* 判断是否为回文的方法:
* 1. 从中心往两边扩充,中心可能是一个字符,也可能是两个字符
* 2. dp,利用之前计算的结果,只判断边缘两个字符是否相等,从后往前dp
......
package code;
import java.util.Arrays;
/*
* 132. Palindrome Partitioning II
* 题意:最少切几刀,回文串
* 难度:Hard
* 分类:Dynamic Programming
* 思路:和lc300思路很像,只是多了判断。dp[i]表示从0到i这一段切法的最小值,每次遍历前边的结果,看能否接上。
* 可以把判断回文和dp两个合并,因为用dp的形式判断回文
* Tips:lc300
* bingo!
*/
public class lc132 {
public int minCut(String s) {
int[] dp = new int[s.length()+1];
Arrays.fill(dp, s.length()); //fill最大值
dp[0] = 0;
for(int i=1; i<dp.length; i++){
for(int j=0; j<=i; j++){ //注意<=
if(dp[j]!=s.length() && isPalindrome(s.substring(j,i)))
dp[i] = Math.min(dp[i], dp[j]+1);
}
}
return dp[s.length()]-1; //要-1 最后一刀是在末尾
}
public Boolean isPalindrome(String str){
if(new StringBuilder(str).reverse().toString().equals(str)) return true; //reverse一下
else return false;
}
public int minCut2(String s) {
char[] c = s.toCharArray();
int n = c.length;
int[] cut = new int[n];
boolean[][] pal = new boolean[n][n];
for(int i = 0; i < n; i++) {
int min = i;
for(int j = 0; j <= i; j++) {
if(c[j] == c[i] && (j + 1 > i - 1 || pal[j + 1][i - 1])) {
pal[j][i] = true;
min = j == 0 ? 0 : Math.min(min, cut[j - 1] + 1);
}
}
cut[i] = min;
}
return cut[n - 1];
}
}
......@@ -6,8 +6,10 @@ package code;
* 分类:Dynamic Programming
* 思路:动态规划
* Tips:巧妙的方法,防止了复杂的操作,通过遍历之前计算出来的结果
* 递归的方法本质和dp是一样的,记住用备忘录算法,把之前的结果记下来
* lc140
*/
import java.util.HashMap;
import java.util.List;
public class lc139 {
......@@ -22,4 +24,16 @@ public class lc139 {
}
return dp[s.length()];
}
HashMap<String, Boolean> hm = new HashMap();
public boolean wordBreak2(String s, List<String> wordDict) {
if(hm.containsKey(s)) return hm.get(s);
if(s.length() == 0) return true;
Boolean flag = false;
for(String word:wordDict){
if(s.startsWith(word)) flag = flag||wordBreak(s.substring(word.length()), wordDict); //注意函数 startsWith
}
hm.put(s, flag);
return flag;
}
}
......@@ -14,15 +14,13 @@ public class lc141 {
ListNode(int x) { val = x; }
}
public boolean hasCycle(ListNode head) {
if(head==null)
return false;
ListNode faster = head;
if(head==null||head.next==null) return false;
ListNode slow = head;
while( faster.next!=null && faster.next.next!=null){ //注意判断条件,slow一定不等于null,不用判断了
ListNode fast = head.next;
while(fast!=null&&fast.next!=null){ //注意判断条件,slow一定不等于null,不用判断了
slow = slow.next;
faster = faster.next.next;
if(slow==faster)
return true;
fast = fast.next.next;
if(fast==slow) return true;
}
return false;
}
......
......@@ -32,4 +32,23 @@ public class lc142 {
}
return null;
}
public ListNode detectCycle2(ListNode head) {
if(head==null||head.next==null) return null;
ListNode slow = head;
ListNode fast = head.next;
while(fast!=null&&fast.next!=null){
slow = slow.next;
fast = fast.next.next;
if(slow==fast){
slow = slow.next;
while(head!=slow){
head = head.next;
slow = slow.next;
}
return slow;
}
}
return null;
}
}
......@@ -25,7 +25,7 @@ public class lc148 {
if( head==null || head.next == null ){
return head;
}
ListNode slow = head;
ListNode slow = head; //记一下
ListNode fast = head.next;
while( fast!=null && fast.next!=null ){ //把链表分成两半
slow = slow.next;
......
......@@ -23,7 +23,7 @@ public class lc207 {
for (int i = 0; i < prerequisites.length ; i++) {
int node1 = prerequisites[i][0];
int node2 = prerequisites[i][1];
graph[node2][node1] = 1;
graph[node2][node1] = 1; //存下邻接矩阵,方便后续查找是否有边
indegree[node1]++; //存下入度,入度为0时,表示该课程可以修
}
Stack<Integer> st = new Stack();
......
......@@ -19,8 +19,7 @@ public class lc226 {
}
public TreeNode invertTree(TreeNode root) {
//递归
if(root==null)
return null;
if(root==null) return null;
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
......
......@@ -6,6 +6,7 @@ package code;
* 分类:Binary Search, Dynamic Programming
* 思路:基本的思路是dp[i]记录以nums[i]结尾的最长长度,每次遍历 dp[i] 得到dp[i+1],复杂度为O(n^2)。最优的解法是O(nlgn),dp[i]是递增的数组,每次插入时二分查找是lgn。
* Tips:经典题目,记一下
* lc132
*/
import java.util.Arrays;
......
......@@ -27,4 +27,18 @@ public class lc309 {
}
return Math.max(s,b);
}
public int maxProfit2(int[] prices) {
if(prices.length==0) return 0;
int[] sell = new int[prices.length];
int[] buy = new int[prices.length];
sell[0] = 0;
buy[0] = -prices[0];
for(int i=1; i<prices.length; i++){
sell[i] = Math.max(sell[i-1], buy[i-1]+prices[i]);
if(i==1) buy[i] = Math.max(buy[i-1], 0-prices[i]);
else buy[i] = Math.max(buy[i-1], sell[i-2]-prices[i]);
}
return Math.max(sell[prices.length-1],buy[prices.length-1]);
}
}
......@@ -4,12 +4,12 @@ package code;
* 题意:找出排列组合的下一个排列
* 难度:Medium
* 分类:Array
* 思路:从后往前找第一个变小的数x,从这个数之后的数中找出第一个比x大的数,交换,再把之后的数逆序即可
* 思路:从后往前找第一个变小的数x,从后往前找出比第一个x大的数,交换,再把之后的数逆序即可
* Tips:很典型的排列组合题,思路方法记忆一下。注意比较时是否有=。
*/
public class lc31 {
public static void main(String[] args) {
int[] nums = {2,3,1,3,3};
int[] nums = {1,2,3};
nextPermutation(nums);
for (int i:nums){
System.out.println(i);
......@@ -19,27 +19,25 @@ public class lc31 {
public static void nextPermutation(int[] nums) {
int ptr = nums.length-1;
//从后往前找第一个变小的数x
//从后往前找第一个变小的数x 从后往前找出比第一个x大的数
while(ptr>0&&nums[ptr-1]>=nums[ptr]){// 注意是 >= {5,1,1} , 等于--
ptr--;
}
if(ptr!=0){
//从这个数之后的数中找出第一个比x大的数
int n = nums[ptr];
int ptr2 = ptr;
for(int i=ptr+1; i<nums.length; i++){ //这不用这么麻烦,后边的数有序的,这可以简化
if( nums[i]>nums[ptr-1] && nums[i]<=n ) {//注意 <= {2,3,1,3,3}
n = nums[i];
ptr2 = i;
}
ptr--;
if(ptr!=-1){
//从后往前,找比
int val = nums[ptr];
int ptr2 = nums.length-1;
while(ptr2>ptr){
if(nums[ptr2]>nums[ptr]) break;
ptr2--;
}
nums[ptr2] = nums[ptr-1];
nums[ptr-1] = n;
nums[ptr] = nums[ptr2];
nums[ptr2] = val;
}
//把之后的数逆序
ReverseNums(nums,ptr,nums.length-1);
ReverseNums(nums,ptr+1,nums.length-1); //+1,不包含ptr那个位置
}
public static void ReverseNums(int[] nums, int start, int end){
int l = end+start;
......
......@@ -28,7 +28,7 @@ public class lc32 {
else{
if(s.charAt(i-2)=='('){ // 这种情况:(())()
dp[i] = dp[i-2]+2;
}else if(i-2-dp[i-1]>=0 && s.charAt(i-2-dp[i-1])=='('){ // 这种情况:()(())
}else if(i-2-dp[i-1]>=0 && s.charAt(i-2-dp[i-1])=='('){ // 这种情况:()(()) , 第一个判断是判断索引是否合法
dp[i] = dp[i-1] + dp[i-2-dp[i-1]]+2;
}
}
......@@ -49,7 +49,7 @@ public class lc32 {
st.push(i);
else if(ch==')'){
st.pop();
if(st.isEmpty())
if(st.isEmpty()) //截断一下
st.push(i);
res = Math.max(res,i-st.peek());
}
......
......@@ -69,5 +69,21 @@ public class lc416 {
return dp[volumn];
}
public boolean canPartition3(int[] nums) {
int sum = 0;
for(int i: nums) sum+=i;
if(sum%2==1) return false;
sum = sum/2;
boolean[][] dp = new boolean[nums.length+1][sum+1];
for(int i =0; i<=nums.length; i++) dp[i][0]=true; //注意赋值0
for(int i=1; i<=nums.length; i++){
for(int j=1; j<=sum; j++){
dp[i][j] = dp[i-1][j];
if(j>=nums[i-1]) dp[i][j]= dp[i][j] || dp[i-1][j-nums[i-1]]; //注意判断index是否合法
}
}
return dp[nums.length][sum];
}
}
......@@ -17,7 +17,7 @@ public class lc76 {
}
public static String minWindow(String s, String t) {
HashMap<Character,Integer> mp = new HashMap();
for (int i = 0; i < t.length() ; i++) { //统计每个字符出现的个数
for (int i = 0; i < t.length() ; i++) { // 统计每个字符出现的个数
char ch = t.charAt(i);
if(mp.containsKey(ch))
mp.put(ch,mp.get(ch)+1);
......@@ -37,7 +37,7 @@ public class lc76 {
if(mp.get(ch_r)>=0) // <0说明重复了
count++;
}
while(count==t.length()){//右移左指针
while(count==t.length()){//右移左指针,注意这个判定条件
if(right-left+1<res_len){ //更新结果
res_left = left;
res_len = right-left+1;
......@@ -56,4 +56,39 @@ public class lc76 {
return "";
return s.substring(res_left,res_left+res_len);
}
public String minWindow2(String s, String t) {
HashMap<Character, Integer> hm = new HashMap();
char[] t_arr = t.toCharArray();
for(int i=0; i<t_arr.length; i++){
hm.put(t_arr[i], hm.getOrDefault(t_arr[i], 0)+1);
}
int left = 0;
int right = 0;
int count = t.length();
char[] s_arr = s.toCharArray();
int res = Integer.MAX_VALUE;
int res_left = 0;
int res_right = 0;
while(right<s.length()){ //一共两个while
if(hm.containsKey(s_arr[right])){
hm.put(s_arr[right], hm.get(s_arr[right])-1);
if(hm.get(s_arr[right])>=0) count--; //别忘了这一层的判断
}
right++; //在if外边
while(count==0){ //注意判断条件
if(right-left+1<res){ //记录结果
res = right-left+1;
res_left = left;
res_right = right;
}
if(hm.containsKey(s_arr[left])){
hm.put(s_arr[left], hm.get(s_arr[left])+1);
if(hm.get(s_arr[left])>0) count++;
}
left++;
}
}
return s.substring(res_left, res_right);
}
}
......@@ -5,7 +5,7 @@ package code;
* 难度:Medium
* 分类:HashTable, Stack, Tree
* 思路:左节点依次入栈二叉树中序遍历
* Tips:和lc144前序,lc145后序一起看
* Tips:和lc144前序,lc145后序一起看, lc102层次遍历
*/
import java.util.ArrayList;
import java.util.List;
......
......@@ -28,7 +28,7 @@ public class lc978 {
public int maxTurbulenceSize2(int[] A) {
int[] arr = new int[A.length-1];
for(int i=1; i<A.length; i++){
for(int i=1; i<A.length; i++){ //转换成0,1数组
if(A[i]==A[i-1]) arr[i-1] = 0;
else if(A[i]>A[i-1]) arr[i-1] = 1;
else arr[i-1] = -1;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册