diff --git a/DataStructures_Algorithm/DataStructures/pom.xml b/DataStructures_Algorithm/DataStructures/pom.xml
index e36fa45..ea4b98b 100644
--- a/DataStructures_Algorithm/DataStructures/pom.xml
+++ b/DataStructures_Algorithm/DataStructures/pom.xml
@@ -9,6 +9,33 @@
4.0.0
+
+
+ junit
+ junit
+ 4.13.2
+ test
+
+
+ junit
+ junit
+ 4.13.2
+ compile
+
+
+ org.projectlombok
+ lombok
+ RELEASE
+ compile
+
+
+ junit
+ junit
+ 4.13.1
+ compile
+
+
+
DataStructures
diff --git a/DataStructures_Algorithm/DataStructures/src/main/java/com/atguigu/sort/selftry/HeapSort.java b/DataStructures_Algorithm/DataStructures/src/main/java/com/atguigu/sort/selftry/HeapSort.java
new file mode 100644
index 0000000..21d506c
--- /dev/null
+++ b/DataStructures_Algorithm/DataStructures/src/main/java/com/atguigu/sort/selftry/HeapSort.java
@@ -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
+
+
+ }
+
+
+}
diff --git a/DataStructures_Algorithm/DataStructures/src/main/java/com/atguigu/tree/HeapSort.java b/DataStructures_Algorithm/DataStructures/src/main/java/com/atguigu/tree/HeapSort.java
index 2169512..8b2682a 100644
--- a/DataStructures_Algorithm/DataStructures/src/main/java/com/atguigu/tree/HeapSort.java
+++ b/DataStructures_Algorithm/DataStructures/src/main/java/com/atguigu/tree/HeapSort.java
@@ -1,5 +1,7 @@
package com.atguigu.tree;
+import org.junit.Test;
+
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
@@ -17,44 +19,57 @@ public class HeapSort {
// System.out.println(Arrays.toString(arr));
//测试80000个数据进行测试
- int[] arr =new int[8000000];
+ int[] arr = new int[8000000];
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();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
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);
Date date2 = new Date();
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) {
//TODO (1)将无序序列构建成一个堆,根据升序降序需求选择大顶堆或者小顶堆
- //arr.length/2-1求出来的是完全二叉树的最后一个非叶子节点
- for (int i = arr.length/2-1; i >= 0; i--) {
- adjustHeap(arr,i,arr.length);
+ // arr.length/2-1求出来的是完全二叉树的最后一个非叶子节点;
+ // arr.length/2-1是关键,是adjustHeap前提的满足条件的前提
+ for (int i = arr.length / 2 - 1; i >= 0; i--) {
+ adjustHeap(arr, i, arr.length);
}
- int temp=0;
+ int temp = 0;
//TODO (2)将顶对元素与末尾元素交换,将最大元素放置在数组末尾
- //TODO (3)重新调整结构,使其满足堆定义,然后继续交换对顶元素与当前末尾元素,贩毒执行调整+交换步骤,直到整个序列有序
- for (int i = arr.length-1; i >0; i--) {
+ //TODO (3)重新调整结构,使其满足堆定义,然后继续交换对顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序
+ for (int i = arr.length - 1; i > 0; i--) {
//交换
- temp=arr[i];
- arr[i]=arr[0];
- arr[0]=temp;
- adjustHeap(arr,0,i);
+ temp = arr[i];
+ arr[i] = arr[0];
+ arr[0] = temp;
+ adjustHeap(arr, 0, i);//主要就是利用堆顶元素就是最大值来进行处理的
}
@@ -62,7 +77,7 @@ public class HeapSort {
}
/**
- * 前提:该节点的所有子节点都已经是大顶堆了
+ * TODO 前提:该节点的所有子节点都已经是大顶堆了,因为这里需要break
* 将以第i个位置为根节点时以下树,调整成一个大顶堆
*
* @param arr 待调整的数组
@@ -76,20 +91,22 @@ public class HeapSort {
//开始调整
//说明:j = i * 2 + 1 ;这里k就是i节点的左子节点
for (int j = i * 2 + 1; j < length; j = j * 2 + 1) {
+ //TODO 1.寻找左右节点哪一个更大
if (j + 1 < length && arr[j] < arr[j + 1]) {
//左子节点的值小于右子节点的值
j++; //j指向右子节点
}
+ //TODO 2.用左右节点中大值去和他的父节点比较;如果小了直接将父节点变成那个最大的值
if (arr[j] > temp) {
//如果子节点大于父节点
arr[i] = arr[j];//把较大的值赋给当前节点
i = j; //将i指向j,继续循环比较
- }else {
- break;
+ } else {
+ break;//左右子节点都比父节点小,直接break
}
}
//当for循环结束后,我们已经将以i为父节点的树的最大值,放在了i的位置
- arr[i]=temp; //将temp值放在调整后的位置
+ arr[i] = temp; //将temp值放在调整后的位置
}
diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/T78_LengthOfLIS.java b/Leecode/src/main/java/com/markilue/leecode/hot100/T78_LengthOfLIS.java
new file mode 100644
index 0000000..32d2281
--- /dev/null
+++ b/Leecode/src/main/java/com/markilue/leecode/hot100/T78_LengthOfLIS.java
@@ -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;
+ }
+}
diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/T79_RemoveInvalidParentheses.java b/Leecode/src/main/java/com/markilue/leecode/hot100/T79_RemoveInvalidParentheses.java
new file mode 100644
index 0000000..165d2f9
--- /dev/null
+++ b/Leecode/src/main/java/com/markilue/leecode/hot100/T79_RemoveInvalidParentheses.java
@@ -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 set = new HashSet<>();
+ StringBuilder str;
+
+ public List 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 res = new ArrayList();
+
+ public List 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 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;
+
+ }
+
+
+}
diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/T80_MaxProfit.java b/Leecode/src/main/java/com/markilue/leecode/hot100/T80_MaxProfit.java
new file mode 100644
index 0000000..5eb0bb0
--- /dev/null
+++ b/Leecode/src/main/java/com/markilue/leecode/hot100/T80_MaxProfit.java
@@ -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);
+
+ }
+
+
+}
diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/T81_MaxCoins.java b/Leecode/src/main/java/com/markilue/leecode/hot100/T81_MaxCoins.java
new file mode 100644
index 0000000..db1eb47
--- /dev/null
+++ b/Leecode/src/main/java/com/markilue/leecode/hot100/T81_MaxCoins.java
@@ -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];
+ }
+
+}
diff --git a/Leecode/src/main/java/com/markilue/leecode/test/test.java b/Leecode/src/main/java/com/markilue/leecode/test/test.java
index b1e34e2..4e39125 100644
--- a/Leecode/src/main/java/com/markilue/leecode/test/test.java
+++ b/Leecode/src/main/java/com/markilue/leecode/test/test.java
@@ -15,6 +15,16 @@ import java.util.ArrayList;
*/
public class test {
+ static {
+
+
+ System.out.println("hello sta");
+ }
+
+ public static void main(String[] args) {
+ System.out.println("hello world");
+ }
+
//测试ArrayList的index是否发生变化
@Test
diff --git a/Leecode/src/main/java/com/markilue/leecode/test/testAnt.java b/Leecode/src/main/java/com/markilue/leecode/test/testAnt.java
index 80406a4..0e7673b 100644
--- a/Leecode/src/main/java/com/markilue/leecode/test/testAnt.java
+++ b/Leecode/src/main/java/com/markilue/leecode/test/testAnt.java
@@ -1,6 +1,7 @@
package com.markilue.leecode.test;
-import java.util.HashMap;
+import java.util.*;
+
import java.util.Scanner;
/**
@@ -14,53 +15,53 @@ import java.util.Scanner;
public class testAnt {
- 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;
+// public static void main(String[] args) {
//
-// //去除前面的
-// while (left < input.length() && input.charAt(left) == ' ') {
-// left++;
-// }
+// Scanner sc = new Scanner(System.in);
+// String input = sc.nextLine();
//
-// boolean isCapital = true; // 首字母是否大写
-// for (int i = left; i < input.length(); i++) {
-// char c = input.charAt(i);
-// if (c == ' ') {
-// if (i > 0 && input.charAt(i - 1) == '.') {
-// output.deleteCharAt(output.length() - 1);
-// }
-// // 跳过多余的空格
-// while (i < input.length() - 1 && input.charAt(i + 1) == ' ') {
-// i++;
-// }
-// if (input.charAt(i + 1) != '.') {
-// output.append(' ');
-// }
-// } else if (c == '.') {
-// // 句号后面要加一个空格
-// output.append(". ");
-// isCapital = true; // 下一句话的首字母要大写
-// } else {
-// if (isCapital) {
-// // 首字母要大写
-// output.append(Character.toUpperCase(c));
-// isCapital = false;
-// } else {
-// output.append(c);
-// }
-// }
-// }
+// new testAnt().test(input);
+//// StringBuilder output = new StringBuilder();
+//// int left = 0;
+////
+//// //去除前面的
+//// while (left < input.length() && input.charAt(left) == ' ') {
+//// left++;
+//// }
+////
+//// boolean isCapital = true; // 首字母是否大写
+//// for (int i = left; i < input.length(); i++) {
+//// char c = input.charAt(i);
+//// if (c == ' ') {
+//// if (i > 0 && input.charAt(i - 1) == '.') {
+//// output.deleteCharAt(output.length() - 1);
+//// }
+//// // 跳过多余的空格
+//// while (i < input.length() - 1 && input.charAt(i + 1) == ' ') {
+//// i++;
+//// }
+//// if (input.charAt(i + 1) != '.') {
+//// output.append(' ');
+//// }
+//// } else if (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) {
@@ -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 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 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);
+ }
+
}