动态规划
This commit is contained in:
parent
2dabc83adb
commit
1eb60f9be4
48
src/main/java/cn/whaifree/leetCode/Dynamic/LeetCode509.java
Normal file
48
src/main/java/cn/whaifree/leetCode/Dynamic/LeetCode509.java
Normal file
@ -0,0 +1,48 @@
|
||||
package cn.whaifree.leetCode.Dynamic;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/8 11:44
|
||||
* @注释
|
||||
*/
|
||||
public class LeetCode509 {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
System.out.println(new Solution1().fib(10));
|
||||
}
|
||||
|
||||
class Solution {
|
||||
public int fib(int n) {
|
||||
if (n==0) return 0;
|
||||
if (n==1) return 1;
|
||||
return fib(n - 1) + fib(n - 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Solution1 {
|
||||
/**
|
||||
* 1. 确定dp数组(dp table)以及下标的含义
|
||||
* 2. 确定递推公式 dp[i] = dp[i - 1] + dp[i - 2];
|
||||
* 3. dp数组如何初始化 dp[0] = 0; dp[1] = 1;
|
||||
* 4. 确定遍历顺序
|
||||
* 5. 举例推导dp数组 0 1 1 2 3 5 8 13 21 34 55
|
||||
* @param n
|
||||
* @return
|
||||
*/
|
||||
public int fib(int n) {
|
||||
if (n<=1) return n;
|
||||
int[] dp = new int[n + 1];
|
||||
dp[0] = 0;
|
||||
dp[1] = 1;
|
||||
for (int i = 2; i <= n; i++) {
|
||||
dp[i] = dp[i - 1] + dp[i - 2];
|
||||
}
|
||||
return dp[n];
|
||||
}
|
||||
}
|
||||
}
|
44
src/main/java/cn/whaifree/leetCode/Dynamic/LeetCode62.java
Normal file
44
src/main/java/cn/whaifree/leetCode/Dynamic/LeetCode62.java
Normal file
@ -0,0 +1,44 @@
|
||||
package cn.whaifree.leetCode.Dynamic;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/8 12:58
|
||||
* @注释
|
||||
*/
|
||||
public class LeetCode62 {
|
||||
|
||||
@Test
|
||||
public void test(
|
||||
) {
|
||||
System.out.println(new Solution().uniquePaths(3, 3));
|
||||
}
|
||||
|
||||
class Solution {
|
||||
/**
|
||||
* 确定dp[i,j] 该点可能的路径数
|
||||
* 递推公式 dp[i,j]= dp[i-1,j] + dp[i,j-1]
|
||||
* 初始化 dp[0,0]=1
|
||||
* 推
|
||||
* 0 1 1 1 1 1 1
|
||||
* 1 2 3 4 5 6 7
|
||||
* 1 3 6 10 15 21 28
|
||||
* @param m
|
||||
* @param n
|
||||
* @return
|
||||
*/
|
||||
public int uniquePaths(int m, int n) {
|
||||
int[][] dp = new int[m][n];
|
||||
dp[0][0] = 1;
|
||||
for (int i = 0; i < m; i++) {
|
||||
for (int j = 0; j < n; j++) {
|
||||
if (i>=1) dp[i][j] += dp[i - 1][j];
|
||||
if (j>=1) dp[i][j] += dp[i][j - 1];
|
||||
}
|
||||
}
|
||||
return dp[m - 1][n - 1];
|
||||
}
|
||||
}
|
||||
}
|
42
src/main/java/cn/whaifree/leetCode/Dynamic/LeetCode70.java
Normal file
42
src/main/java/cn/whaifree/leetCode/Dynamic/LeetCode70.java
Normal file
@ -0,0 +1,42 @@
|
||||
package cn.whaifree.leetCode.Dynamic;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/8 12:11
|
||||
* @注释
|
||||
*/
|
||||
public class LeetCode70 {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
System.out.println(new Solution().climbStairs(0));
|
||||
}
|
||||
|
||||
class Solution {
|
||||
/**
|
||||
* 1. 确定dp数组含义 dp[i] 表示到这里的方法数
|
||||
* 2. 地推公式 dp[i] = dp[i-1]+dp[i-2]
|
||||
* 3. 初始化 dp[0] = 1;dp[1]=1
|
||||
* 4. 模拟推导1 1 2 3 5 8
|
||||
* 0 1 2 3 4 5
|
||||
* @param n
|
||||
* @return
|
||||
*/
|
||||
public int climbStairs(int n) {
|
||||
if (n <= 1) {
|
||||
return n;
|
||||
}
|
||||
int[] dp = new int[n];
|
||||
dp[0] = 1;
|
||||
dp[1] = 2;
|
||||
for (int i = 2; i < n; i++) {
|
||||
dp[i] = dp[i - 1] + dp[i - 2];
|
||||
}
|
||||
return dp[n-1];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
46
src/main/java/cn/whaifree/leetCode/Dynamic/LeetCode746.java
Normal file
46
src/main/java/cn/whaifree/leetCode/Dynamic/LeetCode746.java
Normal file
@ -0,0 +1,46 @@
|
||||
package cn.whaifree.leetCode.Dynamic;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/8 12:24
|
||||
* @注释
|
||||
*/
|
||||
public class LeetCode746 {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
System.out.println(new Solution().minCostClimbingStairs(new int[]{1,1001}));
|
||||
}
|
||||
|
||||
class Solution {
|
||||
|
||||
/**
|
||||
* 含义 dp[i] 走到这最少支出的花费
|
||||
* 递推公式
|
||||
* dp[i] = min{dp[i-2]+cost[i-2] , dp[i-1]+cost[i-1]}
|
||||
* 初始化 dp[0]=0 dp[1]=0
|
||||
* 模拟推导
|
||||
* 1,100,1,1,1,100,1,1,100,1
|
||||
* 0 0 1 2
|
||||
*
|
||||
* @param cost
|
||||
* @return
|
||||
*/
|
||||
public int minCostClimbingStairs(int[] cost) {
|
||||
//一旦你支付此费用,即可选择向上爬一个或者两个台阶。
|
||||
int length = cost.length;
|
||||
int[] dp = new int[length+1];
|
||||
dp[0] = 0;
|
||||
dp[1] = 0;
|
||||
|
||||
for (int i = 2; i <= length; i++) {
|
||||
// 前面两个数有可能跳到本数,判断前两个数跳本数的代价
|
||||
dp[i] = Math.min(dp[i - 2] + cost[i - 2], dp[i - 1] + cost[i - 1]);
|
||||
}
|
||||
return dp[length];
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,8 @@ package cn.whaifree.leetCode.String;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 28. 找出字符串中第一个匹配项的下标
|
||||
*
|
||||
@ -27,9 +29,9 @@ public class LeetCode28 {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
String haystack = "abc";
|
||||
String needle = "bc";
|
||||
int i = new Solution().strStr(haystack, needle);
|
||||
String haystack = "aabaadaabaaf";
|
||||
String needle = "aabaaf";
|
||||
int i = new Solution1().strStr(haystack, needle);
|
||||
System.out.println(i);
|
||||
}
|
||||
|
||||
@ -47,8 +49,77 @@ public class LeetCode28 {
|
||||
end++;
|
||||
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// KMP
|
||||
class Solution1 {
|
||||
public int strStr(String haystack, String needle) {
|
||||
int[] next = next(needle);
|
||||
System.out.println(Arrays.toString(next));
|
||||
int length = haystack.length();
|
||||
// [0, 1, 0, 1, 2, 0]
|
||||
// aabaadaabaaf
|
||||
// aabaaf
|
||||
int j = 0;
|
||||
for (int i = 0; i < length; i++) {
|
||||
// 往前跳
|
||||
while (j > 0 && needle.charAt(j) != haystack.charAt(i)) {
|
||||
j = next[j - 1];
|
||||
}
|
||||
if (needle.charAt(j) == haystack.charAt(i)) {
|
||||
j++;
|
||||
}
|
||||
if (j == needle.length()) {
|
||||
return i - needle.length() + 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 求Next数组
|
||||
public int[] next(String s) {
|
||||
int[] next = new int[s.length()];
|
||||
int j = 0;
|
||||
for (int i = 1; i < s.length(); i++) {
|
||||
// 不匹配
|
||||
while (j > 0 && s.charAt(i) != s.charAt(j)) {
|
||||
j = next[j - 1];
|
||||
}
|
||||
// 匹配
|
||||
if (s.charAt(i) == s.charAt(j)) {
|
||||
j++;
|
||||
}
|
||||
next[i] = j;
|
||||
}
|
||||
return next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Dfather{
|
||||
static int count = 1;
|
||||
static{
|
||||
System.out.println("Initialize class Dfather");
|
||||
}
|
||||
}
|
||||
|
||||
class Dson extends Dfather{
|
||||
static{
|
||||
System.out.println("Initialize class Dson");
|
||||
}
|
||||
}
|
||||
|
||||
class Test4 {
|
||||
public static void main(String[] args) {
|
||||
String a = "d"; //字面量
|
||||
String b = "d"; //字面量,存常量池
|
||||
System.out.println(a == b);
|
||||
a = new String("d"); //对象,存堆
|
||||
System.out.println("a=" + a);
|
||||
System.out.println("b=" + b);
|
||||
System.out.println(a == b);
|
||||
}
|
||||
}
|
||||
|
71
src/main/java/cn/whaifree/leetCode/String/LeetCode459.java
Normal file
71
src/main/java/cn/whaifree/leetCode/String/LeetCode459.java
Normal file
@ -0,0 +1,71 @@
|
||||
package cn.whaifree.leetCode.String;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/7 11:49
|
||||
* @注释
|
||||
*/
|
||||
public class LeetCode459 {
|
||||
@Test
|
||||
public void test() {
|
||||
String s = "aa";
|
||||
Solution solution = new Solution();
|
||||
boolean repeatedSubstringPattern = solution.repeatedSubstringPattern(s);
|
||||
System.out.println(repeatedSubstringPattern);
|
||||
|
||||
|
||||
String aabaaf = "aabaaf";
|
||||
int[] ints = conNext(new int[aabaaf.length()], aabaaf);
|
||||
System.out.println(Arrays.toString(ints));
|
||||
|
||||
}
|
||||
|
||||
class Solution {
|
||||
|
||||
/**
|
||||
* 如果一个串能s被子串重复出现组成 abcabc 由两个abc组成
|
||||
* - s+s如果能被s组成 abcabcabcabc能被abcabc组成
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public boolean repeatedSubstringPattern(String s) {
|
||||
if (s.length() == 1) {
|
||||
return false;
|
||||
}
|
||||
String contact = s.substring(1) + s.substring(0, s.length() - 1);
|
||||
if (contact.contains(s)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int[] conNext(int[] next, String s) {
|
||||
|
||||
// 1. 初始化
|
||||
int j = 0; // 前缀
|
||||
|
||||
// i 为后缀
|
||||
for (int i = 1; i < next.length; i++) {
|
||||
//如果前缀后缀不相同,不断往前跳前缀
|
||||
while (j > 0 && s.charAt(i) != s.charAt(j)) {
|
||||
j = next[j - 1];
|
||||
}
|
||||
//前后缀相同,设置next[i]为next[i-1]+1, 并且j++
|
||||
if (s.charAt(i) == s.charAt(j)) {
|
||||
j++;
|
||||
}
|
||||
// 表示j前后相同的部分 aabaa 如果j指向b i指向a,那么i前面经历过两次s.i==s.j 对应j=2,那么next i对应位置的下标就是前缀j=2
|
||||
// 实际就是两个指针不断对比,如果一样就继续对比下一个数,如果不一样就让前缀j进行回退
|
||||
next[i] = j;
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
// 如何找到
|
||||
}
|
135
src/main/java/cn/whaifree/leetCode/Tes1.java
Normal file
135
src/main/java/cn/whaifree/leetCode/Tes1.java
Normal file
@ -0,0 +1,135 @@
|
||||
package cn.whaifree.leetCode;
|
||||
|
||||
import cn.whaifree.leetCode.model.TreeNode;
|
||||
|
||||
import java.lang.ref.PhantomReference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/6 19:14
|
||||
* @注释
|
||||
*/
|
||||
public class Tes1 {
|
||||
|
||||
// public static void main(String[] args) {
|
||||
//// new Tes1().localvarGc1();
|
||||
//// new Tes1().localvarGc2();
|
||||
//// new Tes1().localvarGc3();
|
||||
// new Tes1().localvarGc4();
|
||||
// }
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
super.finalize();
|
||||
System.out.println("SystemGCTest 重写了finalize()");
|
||||
}
|
||||
|
||||
/**
|
||||
* -XX:+PrintGCDetail
|
||||
*/
|
||||
public void localvarGc1() {
|
||||
byte[] buffer = new byte[10 * 1024 * 1024];
|
||||
//10MB
|
||||
System.gc(); // 成功回收PSYoungGen,移动到ParOldGen老年代
|
||||
/**
|
||||
* 新生代 PSYoungGen: 15482K->11192K(152576K 10mb
|
||||
* full gc后,移动到老年代 [Full GC (System.gc()) [PSYoungGen: 11192K->0K(152576K)] 0mb [ParOldGen: 8K->10885K(348160K)]
|
||||
* [GC (System.gc()) [PSYoungGen: 15482K->11192K(152576K)] 15482K->11200K(500736K), 0.0059640 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
|
||||
* [Full GC (System.gc()) [PSYoungGen: 11192K->0K(152576K)] [ParOldGen: 8K->10885K(348160K)] 11200K->10885K(500736K), [Metaspace: 3210K->3210K(1056768K)], 0.0060621 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
|
||||
* Heap
|
||||
*/
|
||||
}
|
||||
|
||||
public void localvarGc2() {
|
||||
byte[] buffer = new byte[10 * 1024 * 1024];
|
||||
buffer = null;// 对象已经没被引用,byte[]被回收
|
||||
|
||||
System.gc();
|
||||
/**
|
||||
* 回收 空余的堆new byte[10 * 1024 * 1024];
|
||||
* [GC (System.gc()) [PSYoungGen: 15482K->840K(152576K)] 15482K->848K(500736K), 0.0009380 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
|
||||
* [Full GC (System.gc()) [PSYoungGen: 840K->0K(152576K)] [ParOldGen: 8K->645K(348160K)] 848K->645K(500736K), [Metaspace: 3215K->3215K(1056768K)], 0.0043640 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
|
||||
*/
|
||||
}
|
||||
|
||||
public void localvarGc3() {
|
||||
{
|
||||
byte[] buffer = new byte[10 * 1024 * 1024];
|
||||
}
|
||||
System.gc();
|
||||
/**
|
||||
* - 新生代 10mb
|
||||
* [GC (System.gc()) [PSYoungGen: 15482K->11112K(152576K)] 15482K->11120K(500736K), 0.0064283 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
|
||||
* - 进入老年代
|
||||
* [Full GC (System.gc()) [PSYoungGen: 11112K->0K(152576K)] [ParOldGen: 8K->10882K(348160K)] 11120K->10882K(500736K), [Metaspace: 3169K->3169K(1056768K)], 0.0041698 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]*/
|
||||
}
|
||||
|
||||
public void localvarGc4() {
|
||||
{
|
||||
byte[] buffer = new byte[10 * 1024 * 1024];
|
||||
}
|
||||
int value = 10;
|
||||
System.gc();
|
||||
/**
|
||||
* // 局部变量表长度是2,第一个为this,第二个为value,替换了buffer,所以被回收了
|
||||
* [GC (System.gc()) [PSYoungGen: 15482K->904K(152576K)] 15482K->912K(500736K), 0.0006836 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
|
||||
* [Full GC (System.gc()) [PSYoungGen: 904K->0K(152576K)] [ParOldGen: 8K->669K(348160K)] 912K->669K(500736K), [Metaspace: 3216K->3216K(1056768K)], 0.0043170 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
|
||||
*/
|
||||
}
|
||||
|
||||
public void localvarGc5() {
|
||||
localvarGc1();
|
||||
System.gc();
|
||||
}
|
||||
|
||||
|
||||
public static void main1(String[] args) {
|
||||
TreeNode treeNode = new TreeNode(11);
|
||||
SoftReference<TreeNode> treeNodeSoftReference = new SoftReference<>(treeNode);
|
||||
treeNode = null; // 取消强引用
|
||||
System.out.println(treeNodeSoftReference.get().val);
|
||||
|
||||
System.gc();//回收
|
||||
|
||||
System.out.println(treeNodeSoftReference.get().val); // 堆空间内存足够,不会回收软引用
|
||||
|
||||
try {
|
||||
byte[] bytes = new byte[1024 * 1024 * 7]; //导致资源紧张、不够
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}finally {
|
||||
System.out.println(treeNodeSoftReference.get()); // 在OOM之前,GC软引用对象treeNodeSoftReference
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// 创建一个TreeNode对象并创建其对应的PhantomReference和ReferenceQueue
|
||||
TreeNode treeNode = new TreeNode(11);
|
||||
ReferenceQueue<TreeNode> referenceQueue = new ReferenceQueue<>();
|
||||
PhantomReference<TreeNode> treeNodePhantomReference = new PhantomReference<>(treeNode, referenceQueue);
|
||||
|
||||
// 取消对TreeNode对象的强引用
|
||||
treeNode = null;
|
||||
|
||||
// 尝试输出虚引用的对象,由于虚引用不能直接获取对象,所以此行会报错或无输出
|
||||
// System.out.println(treeNodePhantomReference.get().val); // 不允许直接访问
|
||||
|
||||
// 请求垃圾回收
|
||||
System.gc();
|
||||
|
||||
// 虽然对象可能已经被回收,但由于虚引用特性,此处仍然不会被回收
|
||||
// 需要检查ReferenceQueue来判断对象是否已被垃圾回收器处理
|
||||
if (referenceQueue.poll() != null) {
|
||||
System.out.println("TreeNode对象已被垃圾回收器回收,但虚引用仍然存在");
|
||||
} else {
|
||||
System.out.println("TreeNode对象还未被垃圾回收器回收");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
64
src/main/java/cn/whaifree/radom/LeetCode28.java
Normal file
64
src/main/java/cn/whaifree/radom/LeetCode28.java
Normal file
@ -0,0 +1,64 @@
|
||||
package cn.whaifree.radom;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/8 11:09
|
||||
* @注释
|
||||
*/
|
||||
|
||||
public class LeetCode28 {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
int i = new Solution().strStr("aabaadaabaaf", "aabaaf");
|
||||
System.out.println(i);
|
||||
|
||||
}
|
||||
|
||||
class Solution {
|
||||
public int strStr(String haystack, String needle) {
|
||||
int[] next = constructNext(needle);
|
||||
|
||||
int j = 0;
|
||||
for (int i = 0; i < haystack.length(); i++) {
|
||||
while (j > 0 && haystack.charAt(i) != needle.charAt(j)) {
|
||||
j = next[j - 1];
|
||||
}
|
||||
if (haystack.charAt(i) == needle.charAt(j)) {
|
||||
j++;
|
||||
}
|
||||
if (j == needle.length()) {
|
||||
return i - j + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
// 构造next数组
|
||||
public int[] constructNext(String needle) {
|
||||
int length = needle.length();
|
||||
int[] next = new int[length];
|
||||
int j = 0;// 前缀
|
||||
for (int i = 1; i < length; i++) {
|
||||
// 如果不匹配 往前跳
|
||||
while (j > 0 && needle.charAt(i) != needle.charAt(j)) {
|
||||
j = next[j - 1];
|
||||
}
|
||||
// 如果匹配 设置next[i]=j
|
||||
if (needle.charAt(i) == needle.charAt(j)) {
|
||||
j++;
|
||||
}
|
||||
next[i] = j;
|
||||
}
|
||||
return next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user