leecode更新
This commit is contained in:
parent
e6858db144
commit
ebbaae5e7f
|
|
@ -9,6 +9,33 @@
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.13.2</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.13.2</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>RELEASE</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.13.1</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
<artifactId>DataStructures</artifactId>
|
<artifactId>DataStructures</artifactId>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
package com.atguigu.sort.selftry;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@BelongsProject: DataStructures_Algorithm
|
||||||
|
*@BelongsPackage: com.atguigu.sort.selftry
|
||||||
|
*@Author: markilue
|
||||||
|
*@CreateTime: 2023-03-31 10:26
|
||||||
|
*@Description: TODO 尝试堆排序
|
||||||
|
*@Version: 1.0
|
||||||
|
*/
|
||||||
|
public class HeapSort {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test(){
|
||||||
|
int[] arr = {20, 50, 45, 40, 35,10,30,15,25};
|
||||||
|
//测试80000个数据进行测试
|
||||||
|
// int[] arr = new int[200];
|
||||||
|
// for (int i = 0; i < arr.length; i++) {
|
||||||
|
// arr[i] = (int) (Math.random() * 200); //生成一个[0,80000]的数
|
||||||
|
// }
|
||||||
|
heapSort(arr);
|
||||||
|
System.out.println(Arrays.toString(arr));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void heapSort(int[] arr) {
|
||||||
|
|
||||||
|
if (arr == null) return;
|
||||||
|
//从最后一个非叶子节点开始进行堆化
|
||||||
|
for (int i = arr.length / 2 - 1; i >= 0; i--) {
|
||||||
|
adjustHeap(arr, i, arr.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
//进行交换
|
||||||
|
int temp;
|
||||||
|
for (int i = arr.length - 1; i > 0; i--) {
|
||||||
|
temp = arr[i];
|
||||||
|
arr[i] = arr[0];
|
||||||
|
arr[0] = temp;
|
||||||
|
adjustHeap(arr, 0, i);//把交换完的i放在合适的位置
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void adjustHeap(int[] arr, int i, int length) {
|
||||||
|
|
||||||
|
int temp = arr[i];//记录下以前位置的值
|
||||||
|
|
||||||
|
for (int j = 2 * i + 1; j < length; j++) {
|
||||||
|
//比较左右节点哪一个更大
|
||||||
|
if (j + 1 < length && arr[j] < arr[j + 1]) {
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
if (arr[j] > temp) {
|
||||||
|
//需要进行交换
|
||||||
|
arr[i] = arr[j];
|
||||||
|
i = j;//后续比较j位置的值了
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arr[i] = temp;//找到合适的位置放temp
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package com.atguigu.tree;
|
package com.atguigu.tree;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
@ -17,44 +19,57 @@ public class HeapSort {
|
||||||
// System.out.println(Arrays.toString(arr));
|
// System.out.println(Arrays.toString(arr));
|
||||||
|
|
||||||
//测试80000个数据进行测试
|
//测试80000个数据进行测试
|
||||||
int[] arr =new int[8000000];
|
int[] arr = new int[8000000];
|
||||||
for (int i = 0; i < arr.length; i++) {
|
for (int i = 0; i < arr.length; i++) {
|
||||||
arr[i] = (int)(Math.random()*8000000); //生成一个[0,80000]的数
|
arr[i] = (int) (Math.random() * 8000000); //生成一个[0,80000]的数
|
||||||
}
|
}
|
||||||
Date date1 = new Date();
|
Date date1 = new Date();
|
||||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
String date1Str = simpleDateFormat.format(date1);
|
String date1Str = simpleDateFormat.format(date1);
|
||||||
System.out.println("排序前的时间:"+date1Str); //排序前的时间:2022-02-15 21:19:36
|
System.out.println("排序前的时间:" + date1Str); //排序前的时间:2022-02-15 21:19:36
|
||||||
|
|
||||||
heapSort(arr);
|
heapSort(arr);
|
||||||
Date date2 = new Date();
|
Date date2 = new Date();
|
||||||
String date2Str = simpleDateFormat.format(date2);
|
String date2Str = simpleDateFormat.format(date2);
|
||||||
System.out.println("排序后的时间:"+date2Str); //排序后的时间:2022-02-15 21:19:40
|
System.out.println("排序后的时间:" + date2Str); //排序后的时间:2022-02-15 21:19:40
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
int[] arr = {20, 50, 45, 40, 35,10,30,15,25};
|
||||||
|
//测试80000个数据进行测试
|
||||||
|
// int[] arr = new int[200];
|
||||||
|
// for (int i = 0; i < arr.length; i++) {
|
||||||
|
// arr[i] = (int) (Math.random() * 200); //生成一个[0,80000]的数
|
||||||
|
// }
|
||||||
|
heapSort(arr);
|
||||||
|
System.out.println(Arrays.toString(arr));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 编写一个堆排序的方法
|
* 编写一个堆排序的方法
|
||||||
*/
|
*/
|
||||||
public static void heapSort(int[] arr) {
|
public static void heapSort(int[] arr) {
|
||||||
|
|
||||||
//TODO (1)将无序序列构建成一个堆,根据升序降序需求选择大顶堆或者小顶堆
|
//TODO (1)将无序序列构建成一个堆,根据升序降序需求选择大顶堆或者小顶堆
|
||||||
//arr.length/2-1求出来的是完全二叉树的最后一个非叶子节点
|
// arr.length/2-1求出来的是完全二叉树的最后一个非叶子节点;
|
||||||
for (int i = arr.length/2-1; i >= 0; i--) {
|
// arr.length/2-1是关键,是adjustHeap前提的满足条件的前提
|
||||||
adjustHeap(arr,i,arr.length);
|
for (int i = arr.length / 2 - 1; i >= 0; i--) {
|
||||||
|
adjustHeap(arr, i, arr.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int temp=0;
|
int temp = 0;
|
||||||
//TODO (2)将顶对元素与末尾元素交换,将最大元素放置在数组末尾
|
//TODO (2)将顶对元素与末尾元素交换,将最大元素放置在数组末尾
|
||||||
//TODO (3)重新调整结构,使其满足堆定义,然后继续交换对顶元素与当前末尾元素,贩毒执行调整+交换步骤,直到整个序列有序
|
//TODO (3)重新调整结构,使其满足堆定义,然后继续交换对顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序
|
||||||
for (int i = arr.length-1; i >0; i--) {
|
for (int i = arr.length - 1; i > 0; i--) {
|
||||||
//交换
|
//交换
|
||||||
temp=arr[i];
|
temp = arr[i];
|
||||||
arr[i]=arr[0];
|
arr[i] = arr[0];
|
||||||
arr[0]=temp;
|
arr[0] = temp;
|
||||||
adjustHeap(arr,0,i);
|
adjustHeap(arr, 0, i);//主要就是利用堆顶元素就是最大值来进行处理的
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -62,7 +77,7 @@ public class HeapSort {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 前提:该节点的所有子节点都已经是大顶堆了
|
* TODO 前提:该节点的所有子节点都已经是大顶堆了,因为这里需要break
|
||||||
* 将以第i个位置为根节点时以下树,调整成一个大顶堆
|
* 将以第i个位置为根节点时以下树,调整成一个大顶堆
|
||||||
*
|
*
|
||||||
* @param arr 待调整的数组
|
* @param arr 待调整的数组
|
||||||
|
|
@ -76,20 +91,22 @@ public class HeapSort {
|
||||||
//开始调整
|
//开始调整
|
||||||
//说明:j = i * 2 + 1 ;这里k就是i节点的左子节点
|
//说明:j = i * 2 + 1 ;这里k就是i节点的左子节点
|
||||||
for (int j = i * 2 + 1; j < length; j = j * 2 + 1) {
|
for (int j = i * 2 + 1; j < length; j = j * 2 + 1) {
|
||||||
|
//TODO 1.寻找左右节点哪一个更大
|
||||||
if (j + 1 < length && arr[j] < arr[j + 1]) {
|
if (j + 1 < length && arr[j] < arr[j + 1]) {
|
||||||
//左子节点的值小于右子节点的值
|
//左子节点的值小于右子节点的值
|
||||||
j++; //j指向右子节点
|
j++; //j指向右子节点
|
||||||
}
|
}
|
||||||
|
//TODO 2.用左右节点中大值去和他的父节点比较;如果小了直接将父节点变成那个最大的值
|
||||||
if (arr[j] > temp) {
|
if (arr[j] > temp) {
|
||||||
//如果子节点大于父节点
|
//如果子节点大于父节点
|
||||||
arr[i] = arr[j];//把较大的值赋给当前节点
|
arr[i] = arr[j];//把较大的值赋给当前节点
|
||||||
i = j; //将i指向j,继续循环比较
|
i = j; //将i指向j,继续循环比较
|
||||||
}else {
|
} else {
|
||||||
break;
|
break;//左右子节点都比父节点小,直接break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//当for循环结束后,我们已经将以i为父节点的树的最大值,放在了i的位置
|
//当for循环结束后,我们已经将以i为父节点的树的最大值,放在了i的位置
|
||||||
arr[i]=temp; //将temp值放在调整后的位置
|
arr[i] = temp; //将temp值放在调整后的位置
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
package com.markilue.leecode.hot100;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@BelongsProject: Leecode
|
||||||
|
*@BelongsPackage: com.markilue.leecode.hot100
|
||||||
|
*@Author: markilue
|
||||||
|
*@CreateTime: 2023-03-30 10:14
|
||||||
|
*@Description:
|
||||||
|
* TODO 力扣300 最长递增子序列:
|
||||||
|
* 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。
|
||||||
|
* 子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。
|
||||||
|
*@Version: 1.0
|
||||||
|
*/
|
||||||
|
public class T78_LengthOfLIS {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
// int[] nums={10,9,2,5,3,7,101,18};
|
||||||
|
int[] nums = {1, 3, 6, 7, 9, 4, 10, 5, 6};
|
||||||
|
System.out.println(lengthOfLIS(nums));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 思路:dp
|
||||||
|
* dp[i]表示以0开头以i结尾的数组的最长递增子序列长度
|
||||||
|
* @param nums
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int lengthOfLIS(int[] nums) {
|
||||||
|
|
||||||
|
int[] dp = new int[nums.length];
|
||||||
|
Arrays.fill(dp, 1);
|
||||||
|
int max = 0;
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 1; i < dp.length; i++) {
|
||||||
|
for (int j = 0; j < i; j++) {
|
||||||
|
if (nums[i] > nums[j]) {
|
||||||
|
dp[i] = Math.max(dp[i], dp[j] + 1);
|
||||||
|
}
|
||||||
|
if (max < dp[i]) max = dp[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int lengthOfLIS1(int[] nums) {
|
||||||
|
int N = nums.length;
|
||||||
|
//end[i]表示i+1长度的递增子序列的最小值
|
||||||
|
int[] end = new int[N];
|
||||||
|
end[0] = nums[0];
|
||||||
|
int index = 0;
|
||||||
|
for(int i=1; i< N;i++){
|
||||||
|
if(nums[i] > end[index]){
|
||||||
|
end[++index] = nums[i];
|
||||||
|
} else {
|
||||||
|
for (int j = 0; j <= index; j++) {
|
||||||
|
if (nums[i] <= end[j]) {
|
||||||
|
end[j] = nums[i];//替换对应的位置
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,241 @@
|
||||||
|
package com.markilue.leecode.hot100;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@BelongsProject: Leecode
|
||||||
|
*@BelongsPackage: com.markilue.leecode.hot100
|
||||||
|
*@Author: markilue
|
||||||
|
*@CreateTime: 2023-03-30 10:36
|
||||||
|
*@Description:
|
||||||
|
* TODO 力扣301 删除无效的括号:
|
||||||
|
* 给你一个由若干括号和字母组成的字符串 s ,删除最小数量的无效括号,使得输入的字符串有效。
|
||||||
|
* 返回所有可能的结果。答案可以按 任意顺序 返回。
|
||||||
|
*@Version: 1.0
|
||||||
|
*/
|
||||||
|
public class T79_RemoveInvalidParentheses {
|
||||||
|
|
||||||
|
|
||||||
|
//不知道该怎么去重,就用set存储结果 18ms
|
||||||
|
Set<String> set = new HashSet<>();
|
||||||
|
StringBuilder str;
|
||||||
|
|
||||||
|
public List<String> removeInvalidParentheses(String s) {
|
||||||
|
int lmove = 0;
|
||||||
|
int rmove = 0;
|
||||||
|
str = new StringBuilder(s);
|
||||||
|
//遍历一遍,求出要删除左括号和右括号的数量
|
||||||
|
for (int i = 0; i < s.length(); i++) {
|
||||||
|
if (s.charAt(i) == '(') {
|
||||||
|
lmove++;
|
||||||
|
} else if (s.charAt(i) == ')') {
|
||||||
|
//左右括号可以匹配
|
||||||
|
if (lmove > 0) {
|
||||||
|
lmove--;
|
||||||
|
} else {
|
||||||
|
rmove++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dfs(lmove, rmove, 0);
|
||||||
|
return new ArrayList<>(set);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dfs(int lmove, int rmove, int i) {
|
||||||
|
if (lmove == 0 && rmove == 0) {
|
||||||
|
//判断字符串内括号是否有效
|
||||||
|
if (isValid(str)) {
|
||||||
|
set.add(new String(str.toString()));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//还需要删除的括号个数 小于 能过删除的字符个数
|
||||||
|
if (lmove + rmove > str.length() - i) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//不删除
|
||||||
|
dfs(lmove, rmove, i + 1);
|
||||||
|
|
||||||
|
//删除,分左右括号考虑
|
||||||
|
if (str.charAt(i) == '(' && lmove > 0) {
|
||||||
|
str.deleteCharAt(i);//删除
|
||||||
|
dfs(lmove - 1, rmove, i);//进入下一层,因为删除了i处括号,所以不需要i+1
|
||||||
|
str.insert(i, '(');//恢复现场
|
||||||
|
} else if (str.charAt(i) == ')' && rmove > 0) {
|
||||||
|
str.deleteCharAt(i);//删除
|
||||||
|
dfs(lmove, rmove - 1, i);//进入下一层
|
||||||
|
str.insert(i, ')');//恢复现场
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isValid(StringBuilder str) {
|
||||||
|
int left = 0;
|
||||||
|
for (int i = 0; i < str.length(); i++) {
|
||||||
|
if (str.charAt(i) == '(') {
|
||||||
|
left++;
|
||||||
|
} else if (str.charAt(i) == ')') {
|
||||||
|
left--;
|
||||||
|
}
|
||||||
|
if (left < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//自己去重4ms
|
||||||
|
private List<String> res = new ArrayList<String>();
|
||||||
|
|
||||||
|
public List<String> removeInvalidParentheses1(String s) {
|
||||||
|
int lremove = 0;
|
||||||
|
int rremove = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < s.length(); i++) {
|
||||||
|
if (s.charAt(i) == '(') {
|
||||||
|
lremove++;
|
||||||
|
} else if (s.charAt(i) == ')') {
|
||||||
|
if (lremove == 0) {
|
||||||
|
rremove++;
|
||||||
|
} else {
|
||||||
|
lremove--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
helper(s, 0, lremove, rremove);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void helper(String str, int start, int lremove, int rremove) {
|
||||||
|
if (lremove == 0 && rremove == 0) {
|
||||||
|
if (isValid(str)) {
|
||||||
|
res.add(str);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = start; i < str.length(); i++) {
|
||||||
|
if (i != start && str.charAt(i) == str.charAt(i - 1)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 如果剩余的字符无法满足去掉的数量要求,直接返回
|
||||||
|
if (lremove + rremove > str.length() - i) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 尝试去掉一个左括号
|
||||||
|
if (lremove > 0 && str.charAt(i) == '(') {
|
||||||
|
helper(str.substring(0, i) + str.substring(i + 1), i, lremove - 1, rremove);
|
||||||
|
}
|
||||||
|
// 尝试去掉一个右括号
|
||||||
|
if (rremove > 0 && str.charAt(i) == ')') {
|
||||||
|
helper(str.substring(0, i) + str.substring(i + 1), i, lremove, rremove - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isValid(String str) {
|
||||||
|
int cnt = 0;
|
||||||
|
for (int i = 0; i < str.length(); i++) {
|
||||||
|
if (str.charAt(i) == '(') {
|
||||||
|
cnt++;
|
||||||
|
} else if (str.charAt(i) == ')') {
|
||||||
|
cnt--;
|
||||||
|
if (cnt < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cnt == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test(){
|
||||||
|
String s ="()())()";
|
||||||
|
System.out.println(removeInvalidParentheses2(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//自己尝试一遍
|
||||||
|
public List<String> removeInvalidParentheses2(String s) {
|
||||||
|
|
||||||
|
//统计需要去掉的左括号和右括号的数量
|
||||||
|
|
||||||
|
int left = 0;
|
||||||
|
int right = 0;
|
||||||
|
|
||||||
|
for (char c : s.toCharArray()) {
|
||||||
|
if (c == '(') {
|
||||||
|
left++;
|
||||||
|
} else if (c == ')') {
|
||||||
|
if (left == 0) {
|
||||||
|
right++;
|
||||||
|
} else {
|
||||||
|
left--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
helper1(s, left, right, 0);
|
||||||
|
return res;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void helper1(String s, int left, int right, int start) {
|
||||||
|
if (left == 0 && right == 0) {
|
||||||
|
if (isValid1(s)) {
|
||||||
|
res.add(s);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = start; i < s.length(); i++) {
|
||||||
|
//去重
|
||||||
|
if (i != start && s.charAt(i) == s.charAt(i - 1)) continue;
|
||||||
|
|
||||||
|
if (left + right > s.length() - i) {
|
||||||
|
//怎么删都不够了
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//尝试删除左括号
|
||||||
|
if (left > 0 && s.charAt(i) == '(') {
|
||||||
|
helper1(s.substring(0, i) + s.substring(i + 1), left - 1, right, i + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//尝试删除右括号
|
||||||
|
if (right > 0 && s.charAt(i) == ')') {
|
||||||
|
helper1(s.substring(0, i) + s.substring(i + 1), left, right - 1, i + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isValid1(String s) {
|
||||||
|
int left = 0;
|
||||||
|
for (char c : s.toCharArray()) {
|
||||||
|
if (c == '(') {
|
||||||
|
left++;
|
||||||
|
} else if (c == ')') {
|
||||||
|
if (left == 0) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
left--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return left==0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
package com.markilue.leecode.hot100;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@BelongsProject: Leecode
|
||||||
|
*@BelongsPackage: com.markilue.leecode.hot100
|
||||||
|
*@Author: markilue
|
||||||
|
*@CreateTime: 2023-03-31 11:13
|
||||||
|
*@Description: TODO
|
||||||
|
*@Version: 1.0
|
||||||
|
*/
|
||||||
|
public class T80_MaxProfit {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
int[] prices = {1, 2, 3, 0, 2};
|
||||||
|
System.out.println(maxProfit(prices));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 动态dp,状态分为三种:
|
||||||
|
* 今天手里没有股票且不在冷冻期dp[i][0]
|
||||||
|
* 今天手里没有股票且在冷冻期dp[i][1]
|
||||||
|
* 今天手里有股票dp[i][2]
|
||||||
|
* @param prices
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int maxProfit(int[] prices) {
|
||||||
|
if (prices.length == 1) return 0;
|
||||||
|
|
||||||
|
int[][] dp = new int[prices.length][3];
|
||||||
|
|
||||||
|
dp[0][0] = 0;
|
||||||
|
dp[0][1] = 0;
|
||||||
|
dp[0][2] = -prices[0];
|
||||||
|
|
||||||
|
for (int i = 1; i < prices.length; i++) {
|
||||||
|
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1]);//昨天是冷冻期;或者昨天也没买
|
||||||
|
dp[i][1] = dp[i - 1][2] + prices[i];//必须是今天买入
|
||||||
|
dp[i][2] = Math.max(dp[i - 1][2], dp[i - 1][0] - prices[i]);//必须是今天买入
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.max(dp[dp.length - 1][0], dp[dp.length - 1][1]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//滚动数组优化
|
||||||
|
public int maxProfit1(int[] prices) {
|
||||||
|
if (prices.length == 1) return 0;
|
||||||
|
|
||||||
|
|
||||||
|
int dp0 = 0;
|
||||||
|
int dp1 = 0;
|
||||||
|
int dp2 = -prices[0];
|
||||||
|
|
||||||
|
for (int i = 1; i < prices.length; i++) {
|
||||||
|
int temp = dp0;
|
||||||
|
dp0 = Math.max(dp0, dp1);//昨天是冷冻期;或者昨天也没买
|
||||||
|
dp1 = dp2 + prices[i];//必须是今天买入
|
||||||
|
dp2 = Math.max(dp2, temp - prices[i]);//必须是今天买入
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.max(dp0, dp1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,120 @@
|
||||||
|
package com.markilue.leecode.hot100;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@BelongsProject: Leecode
|
||||||
|
*@BelongsPackage: com.markilue.leecode.hot100
|
||||||
|
*@Author: markilue
|
||||||
|
*@CreateTime: 2023-03-31 11:28
|
||||||
|
*@Description: TODO
|
||||||
|
*@Version: 1.0
|
||||||
|
*/
|
||||||
|
public class T81_MaxCoins {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
int[] nums = {3, 1, 5, 8};
|
||||||
|
System.out.println(maxCoins1(nums));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 思路:优先戳中间最小的
|
||||||
|
* 不对
|
||||||
|
* @param nums
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int maxCoins(int[] nums) {
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
|
int count = nums.length;
|
||||||
|
|
||||||
|
while (nums[0] != -1) {
|
||||||
|
int minIndex = 0;
|
||||||
|
int threshold = nums.length;
|
||||||
|
|
||||||
|
if (count == 3) {
|
||||||
|
boolean flag = false;
|
||||||
|
for (int i = 0; i < nums.length; i++) {
|
||||||
|
if (nums[i] == -1) {
|
||||||
|
threshold = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (nums[i] == 1) {
|
||||||
|
minIndex = i;
|
||||||
|
flag = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (!flag) {
|
||||||
|
minIndex = 1;
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
for (int i = 1; i < nums.length; i++) {
|
||||||
|
if (nums[i] == -1) {
|
||||||
|
threshold = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (nums[minIndex] > nums[i]) {
|
||||||
|
minIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//戳i位置
|
||||||
|
int left;
|
||||||
|
if (minIndex - 1 < 0) {
|
||||||
|
left = 1;
|
||||||
|
} else {
|
||||||
|
left = nums[minIndex - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
int right;
|
||||||
|
if (minIndex + 1 >= threshold) {
|
||||||
|
right = 1;
|
||||||
|
} else {
|
||||||
|
right = nums[minIndex + 1];
|
||||||
|
}
|
||||||
|
result += left * nums[minIndex] * right;
|
||||||
|
System.arraycopy(nums, minIndex + 1, nums, minIndex, threshold - minIndex - 1);
|
||||||
|
nums[threshold - 1] = -1;
|
||||||
|
count--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 官方动态规划法:
|
||||||
|
* dp[i][j]表示填满开区间(i,j)能得到的最多硬币数
|
||||||
|
* 最终答案即为 dp[0][n+1]dp[0][n+1]dp[0][n+1]。实现时要注意到动态规划的次序。
|
||||||
|
* 动态规划:
|
||||||
|
* 速度击败27.13% 内存击败45.56% 43ms
|
||||||
|
* @param nums
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int maxCoins1(int[] nums) {
|
||||||
|
int n = nums.length;
|
||||||
|
int[][] rec = new int[n + 2][n + 2];
|
||||||
|
int[] val = new int[n + 2];
|
||||||
|
val[0] = val[n + 1] = 1;
|
||||||
|
for (int i = 1; i <= n; i++) {
|
||||||
|
val[i] = nums[i - 1];
|
||||||
|
}
|
||||||
|
for (int i = n - 1; i >= 0; i--) {
|
||||||
|
for (int j = i + 2; j <= n + 1; j++) {
|
||||||
|
for (int k = i + 1; k < j; k++) {
|
||||||
|
int sum = val[i] * val[k] * val[j];//计算戳当前点的sum
|
||||||
|
sum += rec[i][k] + rec[k][j];//计算不要这个点之后的左右点的戳开的和
|
||||||
|
rec[i][j] = Math.max(rec[i][j], sum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rec[0][n + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -15,6 +15,16 @@ import java.util.ArrayList;
|
||||||
*/
|
*/
|
||||||
public class test {
|
public class test {
|
||||||
|
|
||||||
|
static {
|
||||||
|
|
||||||
|
|
||||||
|
System.out.println("hello sta");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.println("hello world");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//测试ArrayList的index是否发生变化
|
//测试ArrayList的index是否发生变化
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.markilue.leecode.test;
|
package com.markilue.leecode.test;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
|
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -14,53 +15,53 @@ import java.util.Scanner;
|
||||||
public class testAnt {
|
public class testAnt {
|
||||||
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
// public static void main(String[] args) {
|
||||||
|
|
||||||
Scanner sc = new Scanner(System.in);
|
|
||||||
String input = sc.nextLine();
|
|
||||||
|
|
||||||
new testAnt().test(input);
|
|
||||||
// StringBuilder output = new StringBuilder();
|
|
||||||
// int left = 0;
|
|
||||||
//
|
//
|
||||||
// //去除前面的
|
// Scanner sc = new Scanner(System.in);
|
||||||
// while (left < input.length() && input.charAt(left) == ' ') {
|
// String input = sc.nextLine();
|
||||||
// left++;
|
|
||||||
// }
|
|
||||||
//
|
//
|
||||||
// boolean isCapital = true; // 首字母是否大写
|
// new testAnt().test(input);
|
||||||
// for (int i = left; i < input.length(); i++) {
|
//// StringBuilder output = new StringBuilder();
|
||||||
// char c = input.charAt(i);
|
//// int left = 0;
|
||||||
// if (c == ' ') {
|
////
|
||||||
// if (i > 0 && input.charAt(i - 1) == '.') {
|
//// //去除前面的
|
||||||
// output.deleteCharAt(output.length() - 1);
|
//// while (left < input.length() && input.charAt(left) == ' ') {
|
||||||
// }
|
//// left++;
|
||||||
// // 跳过多余的空格
|
//// }
|
||||||
// while (i < input.length() - 1 && input.charAt(i + 1) == ' ') {
|
////
|
||||||
// i++;
|
//// boolean isCapital = true; // 首字母是否大写
|
||||||
// }
|
//// for (int i = left; i < input.length(); i++) {
|
||||||
// if (input.charAt(i + 1) != '.') {
|
//// char c = input.charAt(i);
|
||||||
// output.append(' ');
|
//// if (c == ' ') {
|
||||||
// }
|
//// if (i > 0 && input.charAt(i - 1) == '.') {
|
||||||
// } else if (c == '.') {
|
//// output.deleteCharAt(output.length() - 1);
|
||||||
// // 句号后面要加一个空格
|
//// }
|
||||||
// output.append(". ");
|
//// // 跳过多余的空格
|
||||||
// isCapital = true; // 下一句话的首字母要大写
|
//// while (i < input.length() - 1 && input.charAt(i + 1) == ' ') {
|
||||||
// } else {
|
//// i++;
|
||||||
// if (isCapital) {
|
//// }
|
||||||
// // 首字母要大写
|
//// if (input.charAt(i + 1) != '.') {
|
||||||
// output.append(Character.toUpperCase(c));
|
//// output.append(' ');
|
||||||
// isCapital = false;
|
//// }
|
||||||
// } else {
|
//// } else if (c == '.') {
|
||||||
// output.append(c);
|
//// // 句号后面要加一个空格
|
||||||
// }
|
//// output.append(". ");
|
||||||
// }
|
//// isCapital = true; // 下一句话的首字母要大写
|
||||||
// }
|
//// } else {
|
||||||
|
//// if (isCapital) {
|
||||||
|
//// // 首字母要大写
|
||||||
|
//// output.append(Character.toUpperCase(c));
|
||||||
|
//// isCapital = false;
|
||||||
|
//// } else {
|
||||||
|
//// output.append(c);
|
||||||
|
//// }
|
||||||
|
//// }
|
||||||
|
//// }
|
||||||
|
////
|
||||||
|
//// System.out.println(output.toString());
|
||||||
|
// sc.close();
|
||||||
//
|
//
|
||||||
// System.out.println(output.toString());
|
// }
|
||||||
sc.close();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void test(String str) {
|
public void test(String str) {
|
||||||
|
|
@ -106,4 +107,68 @@ public class testAnt {
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// public static void main(String[] args) {
|
||||||
|
// Scanner scanner = new Scanner(System.in);
|
||||||
|
// int k = scanner.nextInt();
|
||||||
|
// int count = 0;
|
||||||
|
// for (int i = 0; i < 65536; i++) {
|
||||||
|
// String hex = String.format("%04x", i); // 将整数转换成长度为 4 的十六进制数
|
||||||
|
// if (isGoodHex(hex)) {
|
||||||
|
// count++;
|
||||||
|
// if (count == k) {
|
||||||
|
// System.out.println(hex);
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public static boolean isGoodHex(String hex) {
|
||||||
|
// Set<Character> digits = new HashSet<>();
|
||||||
|
// for (char c : hex.toCharArray()) {
|
||||||
|
// digits.add(c);
|
||||||
|
// }
|
||||||
|
// return digits.size() == 4;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
String s = "????(?"; // 待匹配的字符串
|
||||||
|
int left = 0, right = 0, count = 0; // 分别记录左括号、右括号和合法的括号对的数量
|
||||||
|
Stack<Integer> stack = new Stack<>(); // 栈,用于记录左括号和 '?' 的下标
|
||||||
|
for (int i = 0; i < s.length(); i++) {
|
||||||
|
char c = s.charAt(i);
|
||||||
|
if (c == '(' || c == '?') {
|
||||||
|
stack.push(i);
|
||||||
|
if (c == '(') {
|
||||||
|
left++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (stack.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
stack.pop();
|
||||||
|
if (c == ')') {
|
||||||
|
right++;
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (!stack.isEmpty()) { // 处理剩余的左括号或 '?'
|
||||||
|
int index = stack.pop();
|
||||||
|
if (s.charAt(index) == '(') {
|
||||||
|
left--;
|
||||||
|
} else {
|
||||||
|
right--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count += Math.min(left, right); // '?' 可以代替左括号或右括号,因此左右括号数量较小的值为合法的括号对数量
|
||||||
|
System.out.println(count);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue