leecode更新
This commit is contained in:
parent
b1eeb7c60c
commit
f5a1d35d7c
|
|
@ -0,0 +1,175 @@
|
|||
package com.markilue.leecode.hot100;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Deque;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Stack;
|
||||
|
||||
/**
|
||||
*@BelongsProject: Leecode
|
||||
*@BelongsPackage: com.markilue.leecode.hot100
|
||||
*@Author: markilue
|
||||
*@CreateTime: 2023-03-05 10:59
|
||||
*@Description:
|
||||
* TODO 力扣32题 最长有效括号:
|
||||
* 给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号子串的长度。
|
||||
*@Version: 1.0
|
||||
*/
|
||||
public class T19_LongestValidParentheses {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
// String s = "(())";
|
||||
// String s = "()()";
|
||||
// String s = "(()())";
|
||||
// String s = ")(((((()())()()))()(()))(";
|
||||
String s = ")())";
|
||||
// String s = "()(()";
|
||||
System.out.println(longestValidParentheses3(s));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 思路:其实就是将有效括号 进一步变为了寻找最长,那么可以使用动态规划法
|
||||
* TODO DP五部曲:
|
||||
* 1.dp定义: dp[i][j]表示 以i结尾以j开头的子串 是不是有效括号
|
||||
* 2.dp状态转移方程:
|
||||
* 1. s[i]匹配得上s[j]
|
||||
* dp[i][j]=dp[i-1][j+1]
|
||||
* 3.dp初始化: 为了初始化方便 s[i] s[j]变为s[i-1] dp[i][j]=true
|
||||
* 4.dp遍历顺序:从上到下
|
||||
* 5.dp举例推导:
|
||||
* 暂时有问题
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public int longestValidParentheses(String s) {
|
||||
|
||||
char[] chars = s.toCharArray();
|
||||
|
||||
boolean[][] dp = new boolean[chars.length][chars.length];
|
||||
int maxLength = 0;
|
||||
for (int i = 0; i < chars.length; i++) {
|
||||
for (int j = 0; j < i; j++) {
|
||||
if (isMatch(chars, i, j)) {
|
||||
if (i == j + 1) {
|
||||
dp[i][j] = true;
|
||||
} else {
|
||||
dp[i][j] = dp[i - 1][j + 1];
|
||||
}
|
||||
}
|
||||
|
||||
//判断他前后是不是也能匹配上()()的情况
|
||||
if (dp[i][j]) {
|
||||
int start = j;
|
||||
for (int k = j - 1; k >= 0; k--) {
|
||||
if (dp[j - 1][k]) {
|
||||
dp[i][k] = true;//修复,对应的位置
|
||||
start = k;
|
||||
break;
|
||||
}
|
||||
}//找起始位置
|
||||
if (maxLength < i - start + 1) maxLength = i - start + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return maxLength;
|
||||
|
||||
}
|
||||
|
||||
public boolean isMatch(char[] chars, int i, int j) {
|
||||
return chars[i] == ')' && chars[j] == '(';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 仍然使用stack记录法
|
||||
* 暂时有问题
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public int longestValidParentheses1(String s) {
|
||||
|
||||
char[] chars = s.toCharArray();
|
||||
|
||||
int maxLength = 0;
|
||||
int curLength = 0;
|
||||
|
||||
Stack<Character> stack = new Stack<>();
|
||||
|
||||
for (char aChar : chars) {
|
||||
if (aChar == '(') {
|
||||
stack.push(aChar);
|
||||
} else {
|
||||
if (!stack.isEmpty()) {
|
||||
stack.pop();
|
||||
curLength += 2;
|
||||
if (maxLength < curLength) maxLength = curLength;
|
||||
} else {
|
||||
stack.clear();
|
||||
curLength = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return maxLength;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 官方动态规划法:
|
||||
* TODO
|
||||
* 1.s[i]=‘)’ 且 s[i−1]=‘(’s[i - 1] = \text{‘(’}s[i−1]=‘(’,也就是字符串形如 “……()”“……()”“……()”,我们可以推出:
|
||||
* dp[i]=dp[i−2]+2
|
||||
* 2.s[i]=‘)’s[i] = \text{‘)’}s[i]=‘)’ 且 s[i−1]=‘)’s[i - 1] = \text{‘)’}s[i−1]=‘)’,也就是字符串形如 “……))”“……))”“……))”,我们可以推出: 如果 s[i−dp[i−1]−1]=‘(’s[i - \textit{dp}[i - 1] - 1] = \text{‘(’}s[i−dp[i−1]−1]=‘(’,那么
|
||||
* dp[i]=dp[i−1]+dp[i−dp[i−1]−2]+2
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public int longestValidParentheses2(String s) {
|
||||
int maxans = 0;
|
||||
int[] dp = new int[s.length()];
|
||||
for (int i = 1; i < s.length(); i++) {
|
||||
if (s.charAt(i) == ')') {
|
||||
if (s.charAt(i - 1) == '(') {
|
||||
dp[i] = (i >= 2 ? dp[i - 2] : 0) + 2;
|
||||
} else if (i - dp[i - 1] > 0 && s.charAt(i - dp[i - 1] - 1) == '(') {
|
||||
dp[i] = dp[i - 1] + ((i - dp[i - 1]) >= 2 ? dp[i - dp[i - 1] - 2] : 0) + 2;
|
||||
}
|
||||
maxans = Math.max(maxans, dp[i]);
|
||||
}
|
||||
}
|
||||
return maxans;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 官方栈法:存入栈的是位置
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public int longestValidParentheses3(String s) {
|
||||
int maxans = 0;
|
||||
Deque<Integer> stack = new LinkedList<Integer>();
|
||||
stack.push(-1);
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
if (s.charAt(i) == '(') {
|
||||
stack.push(i);
|
||||
} else {
|
||||
stack.pop();
|
||||
if (stack.isEmpty()) {
|
||||
stack.push(i);
|
||||
} else {
|
||||
maxans = Math.max(maxans, i - stack.peek());//只peek不pop是关键
|
||||
}
|
||||
}
|
||||
}
|
||||
return maxans;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
package com.markilue.leecode.hot100;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
*@BelongsProject: Leecode
|
||||
*@BelongsPackage: com.markilue.leecode.hot100
|
||||
*@Author: markilue
|
||||
*@CreateTime: 2023-03-05 13:45
|
||||
*@Description:
|
||||
* TODO 力扣33题 搜索旋转排序数组:
|
||||
* 整数数组 nums 按升序排列,数组中的值 互不相同 。
|
||||
* 在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,
|
||||
* 使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。
|
||||
* 例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。
|
||||
* 给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。
|
||||
* 你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。
|
||||
*@Version: 1.0
|
||||
*/
|
||||
public class T20_Search {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
int[] nums = {4, 5, 6, 7, 0, 1, 2};
|
||||
int target = 3;
|
||||
System.out.println(search(nums, target));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test1() {
|
||||
int[] nums = {1, 3};
|
||||
int target = 3;
|
||||
System.out.println(search(nums, target));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test2() {
|
||||
int[] nums = {5,1, 3};
|
||||
int target = 1;
|
||||
System.out.println(search(nums, target));
|
||||
}
|
||||
|
||||
/**
|
||||
* 思路: 难度自然在于 设计一个时间复杂度为O(log n)的算法
|
||||
* 时间复杂度logn则必然是考虑二分搜索 因为旋转后的数一定是小于第1个数
|
||||
* 1.先找具体旋转的位置(二分法)
|
||||
* 2.再分为两个区具体去找
|
||||
* 速度击败100% 内存击败42.71%
|
||||
* @param nums
|
||||
* @param target
|
||||
* @return
|
||||
*/
|
||||
public int search(int[] nums, int target) {
|
||||
if (nums.length == 1) {
|
||||
return nums[0] == target ? 0 : -1;
|
||||
}
|
||||
|
||||
int k = searchK(nums, 0, nums.length - 1, nums[0]);
|
||||
if (target < nums[0] || k == 0) {
|
||||
if (target < nums[k]) return -1;
|
||||
return binarySearchTrue(nums, k, nums.length - 1, target);
|
||||
} else {
|
||||
return binarySearchTrue(nums, 0, k - 1, target);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int searchK(int[] nums, int start, int end, int target) {
|
||||
if (start == end) {
|
||||
if (nums[start] < target) return start;
|
||||
return 0;
|
||||
}
|
||||
int mid = start + ((end - start) >> 1);
|
||||
if (nums[mid] < target) {
|
||||
return searchK(nums, start, mid, target);
|
||||
} else {
|
||||
return searchK(nums, mid + 1, end, target);
|
||||
}
|
||||
}
|
||||
|
||||
public int binarySearchTrue(int[] nums, int start, int end, int target) {
|
||||
if (start > end) {
|
||||
return -1;
|
||||
}
|
||||
int mid = start + ((end - start) >> 1);
|
||||
if (nums[mid] < target) {
|
||||
return binarySearchTrue(nums, mid + 1, end, target);
|
||||
} else if (nums[mid] > target) {
|
||||
return binarySearchTrue(nums, start, mid - 1, target);
|
||||
} else {
|
||||
return mid;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 官方二分查找:将两次二分合并在一起;就是增加了一层判断:nums[0]和nums[mid]得到关系
|
||||
* 速度击败100% 内存击败37.71%
|
||||
* @param nums
|
||||
* @param target
|
||||
* @return
|
||||
*/
|
||||
public int search1(int[] nums, int target) {
|
||||
int n = nums.length;
|
||||
if (n == 0) {
|
||||
return -1;
|
||||
}
|
||||
if (n == 1) {
|
||||
return nums[0] == target ? 0 : -1;
|
||||
}
|
||||
int l = 0, r = n - 1;
|
||||
while (l <= r) {
|
||||
int mid = (l + r) / 2;
|
||||
if (nums[mid] == target) {
|
||||
return mid;
|
||||
}
|
||||
if (nums[0] <= nums[mid]) {
|
||||
if (nums[0] <= target && target < nums[mid]) {
|
||||
r = mid - 1;
|
||||
} else {
|
||||
l = mid + 1;
|
||||
}
|
||||
} else {
|
||||
if (nums[mid] < target && target <= nums[n - 1]) {
|
||||
l = mid + 1;
|
||||
} else {
|
||||
r = mid - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue