random
This commit is contained in:
parent
99bda3a447
commit
a2d5497bae
4
pom.xml
4
pom.xml
@ -9,8 +9,8 @@
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
|
||||
|
140
src/main/java/cn/whaifree/LCR/LCR001.java
Normal file
140
src/main/java/cn/whaifree/LCR/LCR001.java
Normal file
@ -0,0 +1,140 @@
|
||||
package cn.whaifree.LCR;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/21 11:35
|
||||
* @注释
|
||||
*/
|
||||
public class LCR001 {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
int a = 15;
|
||||
int b = 2;
|
||||
int c = new Solution1().divide(a, b);
|
||||
System.out.println(c);
|
||||
}
|
||||
|
||||
class Solution {
|
||||
/**
|
||||
* 位运算
|
||||
* @param a
|
||||
* @param b
|
||||
* @return
|
||||
*/
|
||||
public int divide(int a, int b) {
|
||||
/**
|
||||
* 17/3
|
||||
* 3<2 2次 一直到 24-12 ,之间有2^2=4个3,剩下的5再 3<2 只要0次,则5中有2^0个3
|
||||
*/
|
||||
boolean reverse = false;
|
||||
if ((a < 0 && b > 0) || (a > 0 && b < 0)) {
|
||||
reverse = true;
|
||||
}
|
||||
if (a < 0) {
|
||||
a = -a;
|
||||
}
|
||||
if (b < 0) {
|
||||
b = -b;
|
||||
}
|
||||
|
||||
|
||||
int down = 0;
|
||||
int sum = 0;
|
||||
int tmp = a;
|
||||
while (tmp > 0) {
|
||||
sum += down;
|
||||
tmp -= down * b;
|
||||
down = getDown(tmp, b);
|
||||
}
|
||||
|
||||
return reverse ? -sum : sum;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param beDivide
|
||||
* @param divide
|
||||
* @return beDivide包含几个divide
|
||||
*/
|
||||
public int getDown(int beDivide, int divide) {
|
||||
|
||||
int have = 0;
|
||||
int tmp = divide;
|
||||
while (tmp < beDivide) {
|
||||
have++;
|
||||
tmp = tmp << 2;
|
||||
}
|
||||
return 1 << have;
|
||||
}
|
||||
}
|
||||
|
||||
class Solution1 {
|
||||
public int divide(int a, int b) {
|
||||
//特殊情况1, b=1
|
||||
if (b == 1){
|
||||
return a;
|
||||
}
|
||||
//特殊情况2, b=-1
|
||||
if (b == -1){
|
||||
return a == Integer.MIN_VALUE ? Integer.MAX_VALUE : -a;
|
||||
}
|
||||
//特殊情况3, a=0
|
||||
if (a == 0){
|
||||
return 0;
|
||||
}
|
||||
|
||||
//确定符号
|
||||
boolean positive = (a ^ b) >= 0;
|
||||
//为避免溢出, 转换为负数进行计算
|
||||
a = a < 0 ? a : -a;
|
||||
b = b < 0 ? b : -b;
|
||||
//快速相减
|
||||
|
||||
/**
|
||||
* 17/3
|
||||
* 3<2 2次 一直到 24-12 ,之间有2^2=4个3,剩下的5再 3<2 只要0次,则5中有2^0个3
|
||||
*/
|
||||
int quotient = 0;
|
||||
while (a <= b){
|
||||
int base = 1;
|
||||
|
||||
int divisor = b;
|
||||
//使用减法, 避免溢出
|
||||
while (a - divisor <= divisor){
|
||||
divisor <<= 1; // 被除数*2 b=2时 就是 2 4 8 16 不断扩大,直到达到a的一半
|
||||
base <<= 1; // 表示包含的(b 被除数)的个数,后面给他加到quotient中
|
||||
}
|
||||
quotient += base;
|
||||
a -= divisor; // a减去前面已经找到的部分 即 17 找到了前面的12,就17-12=5
|
||||
}
|
||||
return positive ? quotient : -quotient;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Solution2 {
|
||||
public int divide(int a, int b) {
|
||||
|
||||
// 不考虑越界的写法
|
||||
int res = 0;
|
||||
while (a < b) {
|
||||
int count = 1;//记住有几个要加入
|
||||
int copyB = b; // 记录每次的总量
|
||||
while (a - copyB < copyB) {
|
||||
copyB <<= 1;
|
||||
count <<= 1;
|
||||
}
|
||||
res += count;
|
||||
a -= copyB;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
54
src/main/java/cn/whaifree/LCR/LCR089.java
Normal file
54
src/main/java/cn/whaifree/LCR/LCR089.java
Normal file
@ -0,0 +1,54 @@
|
||||
package cn.whaifree.LCR;
|
||||
|
||||
import cn.whaifree.interview.Meituan.Test02;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/21 20:05
|
||||
* @注释
|
||||
*/
|
||||
public class LCR089 {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
int[] values = {2, 7, 9, 3, 1};
|
||||
int result = new Solution().rob(values);
|
||||
System.out.println(result);
|
||||
|
||||
// 类似题目
|
||||
new Test02().sugar(values);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class Solution {
|
||||
public int rob(int[] values) {
|
||||
if (values.length == 1) {
|
||||
return values[0];
|
||||
}
|
||||
|
||||
// dp[i]表示当前最大价值
|
||||
// dp[i]=max(dp[i-1],dp[i-2]+values[i])
|
||||
/**
|
||||
*
|
||||
* 2,7,9,3,1
|
||||
* 2 7 11 11 12
|
||||
*
|
||||
*/
|
||||
|
||||
// 初始化前3个
|
||||
int[] dp = new int[values.length];
|
||||
dp[0] = values[0];
|
||||
dp[1] = Math.max(values[0], values[1]);
|
||||
|
||||
for (int i = 2; i < dp.length; i++) {
|
||||
dp[i] = Math.max(dp[i - 1], dp[i - 2] + values[i]);
|
||||
}
|
||||
|
||||
return dp[values.length - 1];
|
||||
}
|
||||
}
|
||||
}
|
55
src/main/java/cn/whaifree/LCR/LCR090.java
Normal file
55
src/main/java/cn/whaifree/LCR/LCR090.java
Normal file
@ -0,0 +1,55 @@
|
||||
package cn.whaifree.LCR;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/21 20:16
|
||||
* @注释
|
||||
*/
|
||||
public class LCR090{
|
||||
|
||||
@Test
|
||||
public void test()
|
||||
{
|
||||
HashMap<Object, Object> objectObjectHashMap = new HashMap<>();
|
||||
objectObjectHashMap.put(null, "");
|
||||
System.out.println(objectObjectHashMap.get(null));
|
||||
System.out.println(objectObjectHashMap.get("a"));
|
||||
|
||||
int[] nums = {1,2,1,1};
|
||||
System.out.println(new Solution().rob(nums));
|
||||
}
|
||||
|
||||
|
||||
class Solution {
|
||||
public int rob(int[] nums) {
|
||||
if (nums.length == 1) {
|
||||
return nums[0];
|
||||
}
|
||||
if (nums.length == 2) {
|
||||
return Math.max(nums[0], nums[1]);
|
||||
}
|
||||
|
||||
return Math.max(
|
||||
robRange(nums, 0, nums.length - 2),
|
||||
robRange(nums, 1, nums.length - 1)
|
||||
);
|
||||
}
|
||||
|
||||
public int robRange(int[] nums, int start, int end) {
|
||||
int first = nums[start], second = Math.max(nums[start], nums[start + 1]);
|
||||
for (int i = start + 2; i <= end; i++) {
|
||||
int temp = second;
|
||||
second = Math.max(first + nums[i], second);
|
||||
first = temp;
|
||||
}
|
||||
return second;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
133
src/main/java/cn/whaifree/interview/Meituan/Test01.java
Normal file
133
src/main/java/cn/whaifree/interview/Meituan/Test01.java
Normal file
@ -0,0 +1,133 @@
|
||||
package cn.whaifree.interview.Meituan;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
*
|
||||
* <a href="https://www.yuque.com/taxing-qarr6/hxitgt/acebypk1uc68zhi2">...</a>
|
||||
|
||||
*
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/19 11:10
|
||||
* @注释
|
||||
*/
|
||||
public class Test01 {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
String s = "CSDFMTMTDSA";
|
||||
int k = 2;
|
||||
System.out.println(mt(k, s));
|
||||
}
|
||||
|
||||
/**
|
||||
* * MT 是美团的缩写,因此小美很喜欢这两个字母。
|
||||
* * 现在小美拿到了一个仅由大写字母组成字符串,她可以最多操作k次,每次可以修改任意一个字符。小美想知道,操作结束后最多共有多少个"M'和'T'字符?
|
||||
* * 输入描述
|
||||
* * 第一行输入两个正整数n,k,代表字符串长度和操作次数。第二行输入一个长度为n的、仅由大写字母组成的字符串。1<=k<=n<=10^5
|
||||
* * 输出描述
|
||||
* * 输出操作结束后最多共有多少个'M'和'T'字符。
|
||||
* * 示例 1
|
||||
* * 输入
|
||||
* * C++
|
||||
* * 5 2
|
||||
* * M鉀锯撂駙拳顰棛薪廈阗摟粒锟惠拱➋壢草麦耸蟭骚殝騶乳
|
||||
* * 输出
|
||||
* * Plain Text
|
||||
* * A
|
||||
* * A
|
||||
* * 说明
|
||||
* * 修改第三个和第五个字符,形成的字符串为 MTTAM,这样共有 4 个'M'和'T'。
|
||||
*
|
||||
* @param k
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public int mt(int k, String s) {
|
||||
|
||||
int isMt = 0;
|
||||
char[] chars = s.toCharArray();
|
||||
for (char aChar : chars) {
|
||||
if (aChar == 'M' || aChar == 'T') {
|
||||
isMt++;
|
||||
}
|
||||
}
|
||||
|
||||
int isNotMt = chars.length - isMt;
|
||||
if (isNotMt > k) {
|
||||
return k + isMt;
|
||||
}else{
|
||||
return chars.length;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new Test01().mt2();
|
||||
|
||||
// new Test01().mt4();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 小美拿到了一个由正整数组成的数组,但其中有一些元素是未知的(用 0 来表示)。
|
||||
* 现在小美想知道,如果那些未知的元素在区间[,]范围内随机取值的话,数组所有元素之和的最小值和最大值分别是多少?
|
||||
* 共有q次询问。
|
||||
* 输入描述
|
||||
* 第一行输入两个正整数n,q,代表数组大小和询问次数。
|
||||
* 第二行输入n个整数ai,其中如果输入ai的为 0,那么说明ai是未知的。
|
||||
* 接下来的q行,每行输入两个正整数1r,代表一次询问。
|
||||
* Plain Text
|
||||
* 1<=n,q<=10^5
|
||||
* 0<=ai<=10^9
|
||||
* 31<=l<=r<=10^9
|
||||
* 输出描述
|
||||
* 输出q行,每行输出两个正整数,代表所有元素之和的最小值和最大值。
|
||||
*/
|
||||
public void mt2() {
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
int n = scanner.nextInt();
|
||||
int query = scanner.nextInt();
|
||||
|
||||
int[] nums = new int[n];
|
||||
int sum = 0;
|
||||
int isZero = 0;
|
||||
for (int i = 0; i < nums.length; i++) {
|
||||
int inputNumber = scanner.nextInt();
|
||||
if (inputNumber==0) isZero++;
|
||||
nums[i] = inputNumber;
|
||||
sum += inputNumber;
|
||||
}
|
||||
|
||||
for (int i = 0; i < query; i++) {
|
||||
int left = scanner.nextInt();
|
||||
int right = scanner.nextInt();
|
||||
System.out.println("=====");
|
||||
System.out.print(sum + left * isZero + " " + (sum + right * isZero));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void mt4(int[] nums, int k) {
|
||||
int sum = 1;
|
||||
for (int num : nums) {
|
||||
sum *= num;
|
||||
}
|
||||
int ans = 0;
|
||||
for (int i = 0; i < nums.length; i++) {
|
||||
int sub = sum / nums[i];
|
||||
if (nums.length - String.valueOf(sub).lastIndexOf("0") == k) {
|
||||
ans++;
|
||||
}
|
||||
}
|
||||
System.out.println(ans);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
234
src/main/java/cn/whaifree/interview/Meituan/Test02.java
Normal file
234
src/main/java/cn/whaifree/interview/Meituan/Test02.java
Normal file
@ -0,0 +1,234 @@
|
||||
package cn.whaifree.interview.Meituan;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* <a href="https://www.nowcoder.com/discuss/599738882497736704?sourceSSR=search">...</a>
|
||||
*
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/21 19:14
|
||||
* @注释
|
||||
*/
|
||||
public class Test02 {
|
||||
public static void main(String[] args) {
|
||||
new Test02().test();
|
||||
}
|
||||
|
||||
|
||||
public void test() {
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
int number = scanner.nextInt();
|
||||
|
||||
for (int i = 0; i < number; i++) {
|
||||
int num = scanner.nextInt();
|
||||
int[] input = new int[num];
|
||||
for (int j = 0; j < num; j++) {
|
||||
input[j] = scanner.nextInt();
|
||||
}
|
||||
|
||||
int[] output = new int[num];
|
||||
for (int j = 0; j < num; j++) {
|
||||
output[j] = scanner.nextInt();
|
||||
}
|
||||
|
||||
isSuccess(input, output);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void isSuccess(int[] input, int[] output) {
|
||||
LinkedList<Integer> stack = new LinkedList<>();
|
||||
int index = 0;
|
||||
for (int i : input) {
|
||||
stack.push(i);
|
||||
while (!stack.isEmpty() && stack.peek() == output[index++]) {
|
||||
stack.pop();
|
||||
}
|
||||
}
|
||||
if (stack.isEmpty()) {
|
||||
System.out.println("yes");
|
||||
} else {
|
||||
System.out.println("no");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test1() {
|
||||
int[] input = {1, 2, 3, 4, 5};
|
||||
int[] output = {4, 5, 3, 2, 1};
|
||||
System.out.println(new Solution946().validateStackSequences(input, output));
|
||||
}
|
||||
|
||||
class Solution946 {
|
||||
public boolean validateStackSequences(int[] pushed, int[] popped) {
|
||||
return success(pushed, popped);
|
||||
}
|
||||
|
||||
public boolean success(int[] input, int[] output) {
|
||||
LinkedList<Integer> stack = new LinkedList<>();
|
||||
int index = 0;
|
||||
for (int i : input) {
|
||||
stack.push(i);
|
||||
while (!stack.isEmpty() && stack.peek() == output[index]) {
|
||||
index++;
|
||||
stack.pop();
|
||||
}
|
||||
}
|
||||
return stack.isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test2() {
|
||||
sugar(new int[]{3, 1, 2, 7, 10, 2, 4});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param values
|
||||
*/
|
||||
public void sugar(int[] values) {
|
||||
// dp[i]表示当前最大价值
|
||||
// dp[i]=max(dp[i-1],dp[i-3]+values[i])
|
||||
/**
|
||||
*
|
||||
* 3 1 2 7 10 2 4
|
||||
*
|
||||
* 3 3 3 10 13 13 14
|
||||
*
|
||||
*/
|
||||
|
||||
// 初始化前3个
|
||||
int[] dp = new int[values.length];
|
||||
int max = 0;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
max = Math.max(max, values[i]);
|
||||
}
|
||||
for (int i = 0; i < 3; i++) {
|
||||
dp[i] = max;
|
||||
}
|
||||
|
||||
for (int i = 3; i < dp.length; i++) {
|
||||
dp[i] = Math.max(dp[i - 1], dp[i - 3] + values[i]);
|
||||
}
|
||||
|
||||
System.out.println(Arrays.toString(dp));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* dp[i]表示从商品0-i中的最美味值
|
||||
* <p>
|
||||
* 获取最大的k个值,遇到最大的这k个值就必吃
|
||||
* <p>
|
||||
* dp[i] =
|
||||
* 1. 如果values[i]不存在于k大个值,如果这个不吃 dp[i-1]
|
||||
* 2. 如果吃 dp[i-2] + values[i]
|
||||
* 3. 如果存在于最大的k个值 dp[i-1] + values[i]
|
||||
* <p>
|
||||
* 1 2 3 4 5 6 7
|
||||
* <p>
|
||||
* 0 1 2 3 4 5 6
|
||||
* 1 2 4 6 9 12 16
|
||||
*
|
||||
* @param values 美味值
|
||||
* @param k 允许打破的次数
|
||||
*/
|
||||
public int calculateMaxTaste(int[] values, int k) {
|
||||
|
||||
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(k, Comparator.reverseOrder());
|
||||
for (int value : values) {
|
||||
priorityQueue.add(value);
|
||||
}
|
||||
|
||||
ArrayList<Integer> list = new ArrayList<>();
|
||||
for (int i = 0; i < k; i++) {
|
||||
list.add(priorityQueue.poll());
|
||||
}
|
||||
|
||||
int[] dp = new int[values.length];
|
||||
dp[0] = values[0];
|
||||
dp[1] = Math.max(values[0], values[1]);
|
||||
for (int i = 2; i < dp.length; i++) {
|
||||
if (list.contains(values[i])) {
|
||||
System.out.println(i + "打破规则:" + values[i]);
|
||||
dp[i] = dp[i - 1] + values[i]; //打破规则
|
||||
} else {
|
||||
dp[i] = Math.max(dp[i - 1], dp[i - 2] + values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return dp[values.length - 1];
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test3() {
|
||||
int[] values = {1, 2, 3, 4, 5, 6, 7};
|
||||
int k = 1;
|
||||
// sugar(values, k);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCalculateMaxTaste() {
|
||||
|
||||
Test02 strategy = new Test02();
|
||||
// 测试用例1
|
||||
int n1 = 3, k1 = 1;
|
||||
int[] delicious1 = {1, 2, 3};
|
||||
Assert.assertEquals(5, strategy.calculateMaxTaste(delicious1, k1));
|
||||
|
||||
// 测试用例2
|
||||
int n2 = 4, k2 = 2;
|
||||
int[] delicious2 = {1, 2, 3, 4};
|
||||
Assert.assertEquals(9, strategy.calculateMaxTaste(delicious2, k2));
|
||||
|
||||
// 测试用例3
|
||||
int n3 = 5, k3 = 1;
|
||||
int[] delicious3 = {1, 3, 2, 4, 5};
|
||||
Assert.assertEquals(12, strategy.calculateMaxTaste(delicious3, k3));
|
||||
|
||||
// 测试用例4
|
||||
int n4 = 3, k4 = 0;
|
||||
int[] delicious4 = {3, 1, 2};
|
||||
Assert.assertEquals(3, strategy.calculateMaxTaste(delicious4, k4));
|
||||
|
||||
// 测试用例5
|
||||
int n5 = 4, k5 = 1;
|
||||
int[] delicious5 = {1, 1, 1, 1};
|
||||
Assert.assertEquals(3, strategy.calculateMaxTaste(delicious5, k5));
|
||||
|
||||
// 测试用例6
|
||||
int n6 = 6, k6 = 2;
|
||||
int[] delicious6 = {5, 2, 4, 1, 3, 6};
|
||||
Assert.assertEquals(16, strategy.calculateMaxTaste(delicious6, k6));
|
||||
|
||||
// 测试用例7
|
||||
int n7 = 5, k7 = 2;
|
||||
int[] delicious7 = {2, 3, 1, 5, 4};
|
||||
Assert.assertEquals(11, strategy.calculateMaxTaste(delicious7, k7));
|
||||
|
||||
// 测试用例8
|
||||
int n8 = 4, k8 = 0;
|
||||
int[] delicious8 = {4, 3, 2, 1};
|
||||
Assert.assertEquals(4, strategy.calculateMaxTaste(delicious8, k8));
|
||||
|
||||
// 测试用例9
|
||||
int n9 = 6, k9 = 3;
|
||||
int[] delicious9 = {2, 1, 5, 3, 6, 4};
|
||||
Assert.assertEquals(19, strategy.calculateMaxTaste(delicious9, k9));
|
||||
|
||||
// 测试用例10
|
||||
int n10 = 7, k10 = 1;
|
||||
int[] delicious10 = {1, 2, 3, 4, 5, 6, 7};
|
||||
Assert.assertEquals(26, strategy.calculateMaxTaste(delicious10, k10));
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,135 @@
|
||||
package cn.whaifree.leetCode.Array;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
*
|
||||
* 排序算法有这几种:
|
||||
* 常见的排序算法包括但不限于以下这些:
|
||||
* 冒泡排序:从第一个元素开始与右侧元素两两比较并交换,直到右侧成为有序部分。
|
||||
* 选择排序:有序部分在左侧,在剩余元素中找到最小的那个元素,并与剩余元素中第一个元素交换。
|
||||
* 插入排序:有序部分在左侧,将剩余元素中第一个元素不断向左交换,直到此元素处于有序部分恰当位置。
|
||||
* 希尔排序:取一个间隔值,距离为间隔值的元素为一组,将整个数组分为若干组。每组内进行插入排序。缩小间隔值并重复,直到间隔值为1,即所有元素在同一组。
|
||||
*
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/20 14:20
|
||||
* @注释
|
||||
*/
|
||||
public class LeetCode912_SortArrays {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
int[] nums = {5, 2, 3, 1,647,24,7,2,8,2,8,1,54,13,6,234,45,234,64,745,32,56,44,32,38};
|
||||
int[] res = new Solution2().sortArray(nums);
|
||||
System.out.println(Arrays.toString(res));
|
||||
|
||||
int[] ints = Arrays.copyOf(res, res.length);
|
||||
Arrays.sort(nums);
|
||||
System.out.println(Arrays.equals(ints, nums));
|
||||
|
||||
}
|
||||
|
||||
|
||||
class Solution {
|
||||
/**
|
||||
* 冒泡
|
||||
* @param nums
|
||||
* @return
|
||||
*/
|
||||
public int[] sortArray(int[] nums) {
|
||||
boolean isSwap = false;
|
||||
for (int i = 0; i < nums.length; i++) {
|
||||
for (int j = 1; j < nums.length - i; j++) {
|
||||
if (nums[j] < nums[j - 1]) {
|
||||
isSwap = true;
|
||||
int tmp = nums[j];
|
||||
nums[j] = nums[j - 1];
|
||||
nums[j - 1] = tmp;
|
||||
}
|
||||
|
||||
}
|
||||
if (!isSwap) {
|
||||
return nums;
|
||||
}
|
||||
isSwap = false;
|
||||
}
|
||||
return nums;
|
||||
}
|
||||
}
|
||||
|
||||
class Solution1 {
|
||||
/**
|
||||
* 选择排序
|
||||
* 选择右边区间的最小值与左边替换
|
||||
* @param nums
|
||||
* @return
|
||||
*/
|
||||
public int[] sortArray(int[] nums) {
|
||||
for (int i = 0; i < nums.length; i++) {
|
||||
int minIndex = i;
|
||||
for (int j = i+1; j < nums.length; j++) {
|
||||
if (nums[minIndex] > nums[j]) {
|
||||
minIndex = j;
|
||||
}
|
||||
}
|
||||
// 交换min与i
|
||||
int tmp = nums[i];
|
||||
nums[i] = nums[minIndex];
|
||||
nums[minIndex] = tmp;
|
||||
}
|
||||
return nums;
|
||||
}
|
||||
}
|
||||
|
||||
class Solution2 {
|
||||
/**
|
||||
* 插入排序 j不断往前插入替换到合适位置
|
||||
* @param nums
|
||||
* @return
|
||||
*/
|
||||
public int[] sortArray(int[] nums) {
|
||||
for (int i = 1; i < nums.length; i++) {
|
||||
int j = i;
|
||||
while (j > 0 && nums[j] < nums[j - 1]) {
|
||||
// 交换j和j-1
|
||||
int tmp = nums[j];
|
||||
nums[j] = nums[j - 1];
|
||||
nums[j - 1] = tmp;
|
||||
j--;
|
||||
}
|
||||
}
|
||||
return nums;
|
||||
}
|
||||
}
|
||||
|
||||
class SolutionQuickSort {
|
||||
/**
|
||||
* 插入排序 j不断往前插入替换到合适位置
|
||||
*
|
||||
*
|
||||
* @param nums
|
||||
* @return
|
||||
*/
|
||||
public int[] sortArray(int[] nums) {
|
||||
|
||||
|
||||
return nums;
|
||||
}
|
||||
|
||||
public void part(int[] nums, int start, int end) {
|
||||
if (start > end) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
114
src/main/java/cn/whaifree/leetCode/Dynamic/LeetCode1049.java
Normal file
114
src/main/java/cn/whaifree/leetCode/Dynamic/LeetCode1049.java
Normal file
@ -0,0 +1,114 @@
|
||||
package cn.whaifree.leetCode.Dynamic;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/18 14:31
|
||||
* @注释
|
||||
*/
|
||||
public class LeetCode1049 {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
int[] stones = {1,2};
|
||||
int result = new Solution1().lastStoneWeightII(stones);
|
||||
System.out.println(result);
|
||||
}
|
||||
|
||||
class Solution {
|
||||
/**
|
||||
* 背包容量为half,让其尽可能装满,除非装不下了。到装不下了,这一部分已经装入的就是拿来碰撞的。剩下就是sum-dp[half]-dp[half]
|
||||
*
|
||||
* 目标就是让石头的总价值分为两部分
|
||||
*
|
||||
* 转换为背包问题
|
||||
*
|
||||
* dp[j] 表示 容量为j的背包最多能够容纳多少价值的物品
|
||||
* - 物品i的价值 为 stones[i]
|
||||
* - 物品i的重量 为 stones[i]
|
||||
*
|
||||
* 1 <= stones.length <= 30
|
||||
* 1 <= stones[i] <= 100
|
||||
* 初始化为store[half]
|
||||
*
|
||||
*
|
||||
* 递推公式 dp[j] = Math.max(dp[j],dp[j-weight[i]]+value[i])
|
||||
* 分成两堆石头,一堆石头的总重量是dp[half],另一堆就是sum - dp[half]。
|
||||
*
|
||||
* @param stones
|
||||
* @return
|
||||
*/
|
||||
public int lastStoneWeightII(int[] stones) {
|
||||
int sum = 0;
|
||||
for (int stone : stones) {
|
||||
sum += stone;
|
||||
}
|
||||
|
||||
int half = sum / 2;
|
||||
int[] dp = new int[half + 1];
|
||||
for (int i = 0; i < stones.length; i++) {
|
||||
for (int j = half; j >= stones[i]; j--) { // 确保背包能够放下
|
||||
dp[j] = Math.max(dp[j], dp[j - stones[i]] + stones[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// dp[half] 是要被消灭的,那两个部分的消灭就*2
|
||||
return sum - dp[half] * 2;
|
||||
}
|
||||
}
|
||||
|
||||
class Solution1 {
|
||||
/**
|
||||
* half = sum/2
|
||||
*
|
||||
*
|
||||
* dp[i][j] 表示 放入i后,容量为j的背包的最大价值
|
||||
*
|
||||
* 1. 放入i dp[i][j] = dp[i-1][j-weight[i]]+value[i]
|
||||
* 2. 不放入i dp[i][j] = dp[i-1][j]
|
||||
*
|
||||
* 2 4 1 1 target=4
|
||||
*
|
||||
* 0 1 2 3 4
|
||||
* 0 0 0 2 2 2
|
||||
* 1 0 0 2 2 2
|
||||
* 2 0 1 3 3 3
|
||||
* 3 0 1 4 4 4
|
||||
*
|
||||
* @param stones
|
||||
* @return
|
||||
*/
|
||||
public int lastStoneWeightII(int[] stones) {
|
||||
int sum = 0;
|
||||
for (int stone : stones) {
|
||||
sum += stone;
|
||||
}
|
||||
// 计算所有石头的总重量,并将其的一半作为目标重量
|
||||
int half = sum / 2;
|
||||
|
||||
int length = stones.length;
|
||||
int[][] dp = new int[length][half + 1];
|
||||
|
||||
for (int i = stones[0]; i <= half; i++) {
|
||||
dp[0][i] = stones[0];
|
||||
}
|
||||
for (int i = 1; i < length; i++) {
|
||||
for (int j = 1; j <= half ; j++) {
|
||||
if (j < stones[i]) {
|
||||
// 放不下 就不放了,价值为i-1物品的最大价值
|
||||
// 当前石头重量大于目标重量,无法放入,价值等于前i-1个石头的最大价值
|
||||
dp[i][j] = dp[i - 1][j];
|
||||
}else {
|
||||
// 取放入和不放入当前石头两种情况中的最大价值
|
||||
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - stones[i]] + stones[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 返回石头总重量减去最接近目标重量的那堆石头的两倍重量
|
||||
return sum - dp[length - 1][half] * 2;
|
||||
}
|
||||
}
|
||||
}
|
173
src/main/java/cn/whaifree/leetCode/Dynamic/LeetCode494.java
Normal file
173
src/main/java/cn/whaifree/leetCode/Dynamic/LeetCode494.java
Normal file
@ -0,0 +1,173 @@
|
||||
package cn.whaifree.leetCode.Dynamic;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/18 16:17
|
||||
* @注释
|
||||
*/
|
||||
public class LeetCode494 {
|
||||
|
||||
@Test
|
||||
public void test()
|
||||
{
|
||||
int[] nums = {1,1,1,1,1};
|
||||
int target = 3;
|
||||
System.out.println(new Solution2().findTargetSumWays(nums, target));
|
||||
}
|
||||
|
||||
class Solution {
|
||||
/**
|
||||
* 背包容量为3
|
||||
* left(+1的数量)-right(-1的数量) = target
|
||||
* left-right = target
|
||||
* left+right = sum (right = sum -left)
|
||||
* left = (target + sum)/2
|
||||
* 表示正数有多少个是固定的,就是我们的背包容量
|
||||
*
|
||||
*
|
||||
* 使用nums[i] 里面全是1 装满容量为left的背包,有几种方法
|
||||
*
|
||||
* if j> nums[i]
|
||||
* dp[i][j] = dp[i-1][j] + dp[i-1][j-nums[i]]
|
||||
* 不放 放
|
||||
* else
|
||||
* dp[i][j] = dp[i-1][j]
|
||||
* 1,1,1,1,1
|
||||
*
|
||||
* 0 1 2 3 4
|
||||
* 0 1 1 0 0 0
|
||||
* 1 0 0 1 0 0
|
||||
* 2 0 3
|
||||
* 3
|
||||
* 4
|
||||
*
|
||||
* @param nums
|
||||
* @param target
|
||||
* @return
|
||||
*/
|
||||
public int findTargetSumWays(int[] nums, int target) {
|
||||
|
||||
int sum = 0;
|
||||
for (int num : nums) {
|
||||
sum += num;
|
||||
}
|
||||
|
||||
// 总和还比不过绝对值,1不够用
|
||||
if(sum < Math.abs(target)){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// left 为+1的数量 +1的数量必须是整数
|
||||
if((sum + target) % 2 != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int left = (sum + target) >> 1; // (sum + target) / 2;
|
||||
|
||||
|
||||
int length = nums.length;
|
||||
int[][] dp = new int[length + 1][left + 1];
|
||||
|
||||
|
||||
// 01背包
|
||||
// i(1 ~ len)表示遍历(不一定选)了 i 个元素,j(0 ~ sum) 表示它们的和
|
||||
dp[0][0] = 1;
|
||||
for (int i = 1; i <= length; i++) {
|
||||
for (int j = 0; j <= left; j++) {
|
||||
// 装不下(不选当前元素)
|
||||
if (j - nums[i - 1] < 0) {
|
||||
dp[i][j] = dp[i - 1][j];
|
||||
// 可装可不装(当前元素可选可不选)
|
||||
} else {
|
||||
dp[i][j] = dp[i - 1][j] + dp[i - 1][j - nums[i - 1]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化:0个元素,和为0,情况有1种(因为没有元素,所以只能不选,和为0):dp[0][0] = 1
|
||||
* 不选当前元素,即"部分和"(即j)与之前相同:dp[i][j] = dp[i - 1][j]
|
||||
* 可选可不选,不选的情况是2,选当前元素的话则之前的状态应为dp[i - 1][j - num](这里的num指的是当前元素的值,即代码中的nums[i - 1]),二者相加,即:dp[i][j] = dp[i - 1][j] + dp[i - 1][j - num]
|
||||
*/
|
||||
|
||||
return dp[length][left];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class Solution1 {
|
||||
|
||||
public int findTargetSumWays(int[] nums, int S) {
|
||||
int sum = 0;
|
||||
for (int num : nums) {
|
||||
sum += num;
|
||||
}
|
||||
// 背包容量为整数,sum + S为奇数的话不满足要求
|
||||
if (((sum + S) & 1) == 1) {
|
||||
return 0;
|
||||
}
|
||||
// 目标和不可能大于总和
|
||||
if (S > sum) {
|
||||
return 0;
|
||||
}
|
||||
sum = (sum + S) >> 1;
|
||||
int len = nums.length;
|
||||
int[][] dp = new int[len + 1][sum + 1];
|
||||
dp[0][0] = 1;
|
||||
|
||||
// 如果迭代部分 j 的初值赋 1 的话,就要先初始化 j = 0 的情况
|
||||
/* int count = 1;
|
||||
for (int i = 1; i <= len; i++) {
|
||||
// ±0 均可
|
||||
if (nums[i - 1] == 0) {
|
||||
count *= 2;
|
||||
}
|
||||
dp[i][0] = count;
|
||||
} */
|
||||
|
||||
// 01背包
|
||||
// i(1 ~ len)表示遍历(不一定选)了 i 个元素,j(0 ~ sum) 表示它们的和
|
||||
for (int i = 1; i <= len; i++) {
|
||||
for (int j = 0; j <= sum; j++) {
|
||||
// 装不下(不选当前元素)
|
||||
if (j - nums[i - 1] < 0) {
|
||||
dp[i][j] = dp[i - 1][j];
|
||||
// 可装可不装(当前元素可选可不选)
|
||||
} else {
|
||||
dp[i][j] = dp[i - 1][j] + dp[i - 1][j - nums[i - 1]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dp[len][sum];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Solution2 {
|
||||
public int findTargetSumWays(int[] nums, int S) {
|
||||
int sum = 0;
|
||||
for(int i=0; i<nums.length; i++){
|
||||
sum += nums[i];
|
||||
nums[i] += nums[i];
|
||||
}
|
||||
if(S>sum) return 0;
|
||||
S += sum;
|
||||
int[] dp = new int[S+1];
|
||||
dp[0] = 1;
|
||||
for(int num: nums){
|
||||
for(int i=S; i>=0; i--){
|
||||
if(i-num>=0){
|
||||
dp[i] = dp[i] + dp[i-num];
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[S];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
98
src/main/java/cn/whaifree/leetCode/Dynamic/LeetCode647.java
Normal file
98
src/main/java/cn/whaifree/leetCode/Dynamic/LeetCode647.java
Normal file
@ -0,0 +1,98 @@
|
||||
package cn.whaifree.leetCode.Dynamic;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/22 12:36
|
||||
* @注释
|
||||
*/
|
||||
public class LeetCode647 {
|
||||
|
||||
class Solution {
|
||||
/**
|
||||
* 判断一个子字符串(字符串的下表范围[i,j])是否回文,
|
||||
* 依赖于子字符串(下表范围[i + 1, j - 1])) 是否是回文。
|
||||
*
|
||||
* 布尔类型的dp[i][j]:表示区间范围[i,j] (注意是左闭右闭)的子串是否是回文子串
|
||||
*
|
||||
* ij两个循环,能够覆盖所有循环
|
||||
* - dp[i][j] 判断是否回文的时候,只需要dp[i+1][j-1]是否回文,并且s[i]==s[j]
|
||||
* 当s[i]=s[j]
|
||||
* 1. i=j 回文
|
||||
* 2. i+1=j 回文
|
||||
* 3. dp[i+1][j-1]==true 回文
|
||||
*
|
||||
*
|
||||
* <img src="https://code-thinking-1253855093.file.myqcloud.com/pics/20210121171032473-20230310132134822.jpg" alt="">
|
||||
* dp[i][j]由dp[i+1][j-1]过来,所以必须从下到上,左到右
|
||||
*
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public int countSubstrings(String s) {
|
||||
|
||||
char[] chars = s.toCharArray();
|
||||
|
||||
boolean[][] dp = new boolean[chars.length][chars.length];
|
||||
int res = 0;
|
||||
for (int i = s.length() - 1; i >= 0; i--) {
|
||||
for (int j = i; j < s.length(); j++) {
|
||||
if (chars[i] == chars[j]) {
|
||||
if (j - i == 1|| i==j || dp[i + 1][j - 1]) {
|
||||
dp[i][j] = true;
|
||||
res++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class Solution1 {
|
||||
public int countSubstrings(String s) {
|
||||
// 中心点向外扩充
|
||||
// 1个元素可以作为中心点
|
||||
// 2个元素也能作为中心点
|
||||
char[] chars = s.toCharArray();
|
||||
int res = 0;
|
||||
for (int i = 0; i < chars.length; i++) {
|
||||
res += subString(chars, i, i);
|
||||
res += subString(chars, i, i + 1);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param chars
|
||||
* @param center1 向左扩展的指针
|
||||
* @param center2 向右扩展的指针
|
||||
* @return 有几个子串
|
||||
*/
|
||||
public int subString(char[] chars, int center1, int center2) {
|
||||
int res = 0;
|
||||
while (center1 >= 0 && center2 < chars.length && chars[center1] == chars[center2]) {
|
||||
center1--;
|
||||
center2++;
|
||||
res++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test()
|
||||
{
|
||||
Solution1 solution = new Solution1();
|
||||
String s = "aaa";
|
||||
int res = solution.countSubstrings(s);
|
||||
System.out.println(res);
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package cn.whaifree.leetCode.Greedy;
|
||||
|
||||
import jdk.internal.instrumentation.InstrumentationTarget;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
|
@ -2,7 +2,7 @@ package cn.whaifree.leetCode.Greedy;
|
||||
|
||||
import cn.whaifree.leetCode.Tree.LeetCode94;
|
||||
import org.junit.Test;
|
||||
import sun.misc.Launcher;
|
||||
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
|
95
src/main/java/cn/whaifree/leetCode/LeetCode/LeetCode4.java
Normal file
95
src/main/java/cn/whaifree/leetCode/LeetCode/LeetCode4.java
Normal file
@ -0,0 +1,95 @@
|
||||
package cn.whaifree.leetCode.LeetCode;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/21 16:57
|
||||
* @注释
|
||||
*/
|
||||
public class LeetCode4 {
|
||||
|
||||
@Test
|
||||
public void test()
|
||||
{
|
||||
Solution2 solution = new Solution2();
|
||||
int[] nums1 = {1,3};
|
||||
int[] nums2 = {2};
|
||||
double medianSortedArrays = solution.findMedianSortedArrays(nums1, nums2);
|
||||
System.out.println(medianSortedArrays);
|
||||
}
|
||||
|
||||
class Solution1 {
|
||||
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
|
||||
int length = nums1.length + nums2.length;
|
||||
int middle = length / 2;
|
||||
int index1 = 0;
|
||||
int index2 = 0;
|
||||
|
||||
boolean flag = false;
|
||||
while (index1 + index2 < middle - 1) {
|
||||
if (nums1[index1] < nums2[index2]) {
|
||||
flag = false;
|
||||
index1++;
|
||||
} else {
|
||||
flag = true;
|
||||
index2++;
|
||||
}
|
||||
}
|
||||
|
||||
if (length % 2 != 0) {
|
||||
return flag ? nums2[index2] : nums1[index1];
|
||||
}else {
|
||||
return (double) (nums1[index1] + nums2[index2]) / 2;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class Solution {
|
||||
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
|
||||
|
||||
int[] nums = new int[nums1.length + nums2.length];
|
||||
int indexA = 0;
|
||||
int indexB = 0;
|
||||
int index = 0;
|
||||
while (indexA < nums1.length && indexB < nums2.length) {
|
||||
if (nums1[indexA] <= nums2[indexB]) {
|
||||
nums[index++] = nums1[indexA++];
|
||||
}else {
|
||||
nums[index++] = nums2[indexB++];
|
||||
}
|
||||
}
|
||||
|
||||
while (indexA < nums1.length) {
|
||||
nums[index++] = nums1[indexA++];
|
||||
}
|
||||
while (indexB < nums2.length) {
|
||||
nums[index++] = nums2[indexB++];
|
||||
}
|
||||
|
||||
int length = nums.length;
|
||||
return length % 2 == 1 ? (double) nums[length / 2] : (double) (nums[length/2 - 1] + nums[length/2]) / 2;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class Solution2 {
|
||||
/**
|
||||
* 二分查找
|
||||
* @param nums1
|
||||
* @param nums2
|
||||
* @return
|
||||
*/
|
||||
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package cn.whaifree.leetCode.LinkedList;
|
||||
|
||||
import cn.whaifree.leetCode.model.ListNode;
|
||||
import com.sun.jmx.remote.internal.ArrayQueue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
37
src/main/java/cn/whaifree/leetCode/Stack/LeetCode946.java
Normal file
37
src/main/java/cn/whaifree/leetCode/Stack/LeetCode946.java
Normal file
@ -0,0 +1,37 @@
|
||||
package cn.whaifree.leetCode.Stack;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/21 19:38
|
||||
* @注释
|
||||
*/
|
||||
public class LeetCode946 {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
new Solution().validateStackSequences(new int[]{1, 2, 3, 4, 5}, new int[]{4, 5, 3, 2, 1});
|
||||
}
|
||||
class Solution {
|
||||
public boolean validateStackSequences(int[] pushed, int[] popped) {
|
||||
return success(pushed, popped);
|
||||
}
|
||||
|
||||
public boolean success(int[] input, int[] output) {
|
||||
LinkedList<Integer> stack = new LinkedList<>();
|
||||
int index = 0;
|
||||
for (int i : input) {
|
||||
stack.push(i);
|
||||
while (!stack.isEmpty() && stack.peek() == output[index]) {
|
||||
index++;
|
||||
stack.pop();
|
||||
}
|
||||
}
|
||||
return stack.isEmpty();
|
||||
}
|
||||
}
|
||||
}
|
102
src/main/java/cn/whaifree/leetCode/String/LeetCode5.java
Normal file
102
src/main/java/cn/whaifree/leetCode/String/LeetCode5.java
Normal file
@ -0,0 +1,102 @@
|
||||
package cn.whaifree.leetCode.String;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/22 12:16
|
||||
* @注释
|
||||
*/
|
||||
public class LeetCode5 {
|
||||
|
||||
@Test
|
||||
public void test()
|
||||
{
|
||||
Solution1 solution = new Solution1();
|
||||
String s = "cbbd";
|
||||
String s1 = solution.longestPalindrome(s);
|
||||
System.out.println(s1);
|
||||
}
|
||||
|
||||
class Solution {
|
||||
/**
|
||||
* 动态规划
|
||||
* dp[i][j] 表示 i-j的串是不是回文串
|
||||
* 同时记录i和j的最大差值的i和j
|
||||
*
|
||||
* s[i] = s[j] 时
|
||||
* dp[i][j] =
|
||||
* 1. i=j true
|
||||
* 2. i=j+1 true
|
||||
* 3. if(dp[i+1][j-1]) true
|
||||
*
|
||||
*
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public String longestPalindrome(String s) {
|
||||
int length = s.length();
|
||||
boolean[][] dp = new boolean[length][length];
|
||||
|
||||
int maxI = 0;
|
||||
int maxJ = 0;
|
||||
|
||||
// dp[i+1][j-1] 决定了dp[i][j] 所以 要从下往上,从左往右遍历
|
||||
for (int i = length; i >= 0; i--) {
|
||||
for (int j = i; j < length; j++) {
|
||||
if (s.charAt(i) == s.charAt(j) && (i == j || i + 1 == j || dp[i + 1][j - 1])) {
|
||||
if ((maxJ - maxI) <= j - i) {
|
||||
maxI = i;
|
||||
maxJ = j;
|
||||
}
|
||||
dp[i][j] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return s.substring(maxI, maxJ+1);
|
||||
}
|
||||
}
|
||||
|
||||
class Solution1 {
|
||||
public String longestPalindrome(String s) {
|
||||
char[] chars = s.toCharArray();
|
||||
// 向外扩展,统计回文长度
|
||||
int length = s.length();
|
||||
int start = 0;
|
||||
int end = 0;
|
||||
for (int i = 0; i < length; i++) {
|
||||
|
||||
int a = getHuiWenLengthReturnLength(chars, i, i);
|
||||
int b = getHuiWenLengthReturnLength(chars, i, i + 1);
|
||||
|
||||
int maxLength = Math.max(a, b);
|
||||
if (maxLength > end - start){
|
||||
start = i - (maxLength - 1) / 2;
|
||||
end = i + maxLength / 2;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return s.substring(start, end + 1);
|
||||
}
|
||||
|
||||
public String getHuiWenLength(char[] chars, int left, int right) {
|
||||
while (left >= 0 && right < chars.length && chars[left] == chars[right]) {
|
||||
left--;
|
||||
right++;
|
||||
}
|
||||
return new String(chars, left + 1, right - left - 1);
|
||||
}
|
||||
|
||||
public int getHuiWenLengthReturnLength(char[] chars, int left, int right) {
|
||||
while (left >= 0 && right < chars.length && chars[left] == chars[right]) {
|
||||
left--;
|
||||
right++;
|
||||
}
|
||||
return right - left - 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package cn.whaifree.leetCode.Tree;
|
||||
|
||||
import cn.whaifree.leetCode.model.TreeNode;
|
||||
import com.sun.org.apache.bcel.internal.generic.NEW;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.*;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package cn.whaifree.leetCode.Tree;
|
||||
|
||||
import cn.whaifree.leetCode.model.TreeNode;
|
||||
import com.sun.org.apache.regexp.internal.RE;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Deque;
|
||||
|
@ -1,12 +1,14 @@
|
||||
package cn.whaifree.leetCode.Tree;
|
||||
|
||||
import cn.whaifree.leetCode.model.TreeNode;
|
||||
import javafx.scene.layout.VBox;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Deque;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
@ -17,6 +19,16 @@ import java.util.List;
|
||||
public class LeetCode513 {
|
||||
@Test
|
||||
public void test() {
|
||||
ExecutorService executor = Executors.newFixedThreadPool(5);
|
||||
executor.submit(new Callable<Object>() {
|
||||
@Override
|
||||
public Object call() throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
TreeNode root = TreeNode.constructTree(new Integer[]{1});
|
||||
root.printTree();
|
||||
System.out.println(new Solution1().findBottomLeftValue(root));
|
||||
|
@ -1,7 +1,7 @@
|
||||
package cn.whaifree.leetCode.Tree;
|
||||
|
||||
import cn.whaifree.leetCode.model.TreeNode;
|
||||
import jdk.nashorn.internal.runtime.RewriteException;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
|
34
src/main/java/cn/whaifree/redo/redoAll/LeetCode203.java
Normal file
34
src/main/java/cn/whaifree/redo/redoAll/LeetCode203.java
Normal file
@ -0,0 +1,34 @@
|
||||
package cn.whaifree.redo.redoAll;
|
||||
|
||||
import cn.whaifree.leetCode.model.ListNode;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/20 14:01
|
||||
* @注释
|
||||
*/
|
||||
public class LeetCode203 {
|
||||
|
||||
@Test
|
||||
public void main() {
|
||||
new Solution().removeElements(ListNode.listNodeFromArray(new int[]{1, 2, 6, 3, 4, 5, 6}), 6).printList();
|
||||
}
|
||||
|
||||
class Solution {
|
||||
public ListNode removeElements(ListNode head, int val) {
|
||||
|
||||
if (head == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
head.next = removeElements(head.next, val);
|
||||
|
||||
if (head.val == val) {
|
||||
return head.next;
|
||||
}
|
||||
return head;
|
||||
}
|
||||
}
|
||||
}
|
35
src/main/java/cn/whaifree/redo/redoAll/LeetCode206.java
Normal file
35
src/main/java/cn/whaifree/redo/redoAll/LeetCode206.java
Normal file
@ -0,0 +1,35 @@
|
||||
package cn.whaifree.redo.redoAll;
|
||||
|
||||
import cn.whaifree.leetCode.model.ListNode;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/20 14:06
|
||||
* @注释
|
||||
*/
|
||||
public class LeetCode206 {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
ListNode listNode = new Solution().reverseList(ListNode.listNodeFromArray(new int[]{1, 2, 3, 4, 5}));
|
||||
listNode.printList();
|
||||
}
|
||||
|
||||
class Solution {
|
||||
public ListNode reverseList(ListNode head) {
|
||||
return reverse(null, head);
|
||||
}
|
||||
|
||||
public ListNode reverse(ListNode before, ListNode after) {
|
||||
if (after == null) {
|
||||
return before;
|
||||
}
|
||||
ListNode tmp = after.next;
|
||||
after.next = before;
|
||||
return reverse(after, tmp);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,12 +1,8 @@
|
||||
package cn.whaifree.redo.redo_24_2_22;
|
||||
|
||||
import cn.whaifree.leetCode.model.ListNode;
|
||||
import cn.whaifree.leetCode.model.TreeNode;
|
||||
import com.sun.xml.internal.ws.server.sei.ValueGetter;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
|
@ -2,7 +2,6 @@ package cn.whaifree.redo.redo_24_3_1;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
|
44
src/main/java/cn/whaifree/redo/redo_24_3_16/LeetCode236.java
Normal file
44
src/main/java/cn/whaifree/redo/redo_24_3_16/LeetCode236.java
Normal file
@ -0,0 +1,44 @@
|
||||
package cn.whaifree.redo.redo_24_3_16;
|
||||
|
||||
import cn.whaifree.leetCode.model.TreeNode;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/17 15:56
|
||||
* @注释
|
||||
*/
|
||||
public class LeetCode236 {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
new Solution().lowestCommonAncestor(TreeNode.constructTreeByArray(1, 2, 3, 4, 5, 6), new TreeNode(4), new TreeNode(5)).printTree();
|
||||
}
|
||||
|
||||
class Solution {
|
||||
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
|
||||
if (root == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (root.val == p.val || root.val == q.val) {
|
||||
return root;
|
||||
}
|
||||
|
||||
TreeNode left = lowestCommonAncestor(root.left, p, q);
|
||||
TreeNode right = lowestCommonAncestor(root.right, p, q);
|
||||
|
||||
if (left != null && right != null) {
|
||||
return root;
|
||||
}
|
||||
|
||||
|
||||
if (left == null) {
|
||||
return right;
|
||||
}else {
|
||||
return left;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
44
src/main/java/cn/whaifree/redo/redo_24_3_16/LeetCode376.java
Normal file
44
src/main/java/cn/whaifree/redo/redo_24_3_16/LeetCode376.java
Normal file
@ -0,0 +1,44 @@
|
||||
package cn.whaifree.redo.redo_24_3_16;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/17 16:09
|
||||
* @注释
|
||||
*/
|
||||
public class LeetCode376 {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
int[] nums = {0,0,0};
|
||||
int res = new Solution().wiggleMaxLength(nums);
|
||||
System.out.println(res);
|
||||
}
|
||||
|
||||
class Solution {
|
||||
public int wiggleMaxLength(int[] nums) {
|
||||
if (nums.length < 2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 记录前一个的正负
|
||||
// 后一个如果和前一个是相反的 res++ 并且相反值变换
|
||||
// 不是相反的 不处理
|
||||
int pre = 0;
|
||||
int cur = 0;
|
||||
|
||||
int res = 1;
|
||||
for (int i = 1; i < nums.length; i++) {
|
||||
cur = nums[i] - nums[i - 1];
|
||||
// pre=0 确保第一次能够进去
|
||||
if ((cur > 0 && pre <= 0) || (cur < 0 && pre >= 0)) {
|
||||
res++;
|
||||
pre = cur;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
142
src/main/java/cn/whaifree/redo/redo_24_3_16/LeetCode416.java
Normal file
142
src/main/java/cn/whaifree/redo/redo_24_3_16/LeetCode416.java
Normal file
@ -0,0 +1,142 @@
|
||||
package cn.whaifree.redo.redo_24_3_16;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/17 17:04
|
||||
* @注释
|
||||
*/
|
||||
public class LeetCode416 {
|
||||
@Test
|
||||
public void test() {
|
||||
int[] nums = {1, 5, 11, 5};
|
||||
boolean canPartition = new Solution().canPartition(nums);
|
||||
System.out.println(canPartition);
|
||||
}
|
||||
|
||||
class Solution {
|
||||
/**
|
||||
* 0-1背包问题
|
||||
*
|
||||
* dp[i][j] 表示 放入物品i后,容量为j的背包的最大价值
|
||||
*
|
||||
* 背包容量为sum/2
|
||||
* 物品重量为nums[i]
|
||||
* 物品价值为nums[i]
|
||||
*
|
||||
* [3,5,11,5]
|
||||
*
|
||||
* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1
|
||||
* 0 0 0 0 3 3
|
||||
* 1
|
||||
* 2
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param nums
|
||||
* @return
|
||||
*/
|
||||
public boolean canPartition(int[] nums) {
|
||||
|
||||
int sum = 0;
|
||||
for (int num : nums) {
|
||||
sum += num;
|
||||
}
|
||||
if (sum % 2 != 0) {
|
||||
return false;
|
||||
}
|
||||
int half = sum / 2;
|
||||
int length = nums.length;
|
||||
int[][] dp = new int[length][half+1];
|
||||
|
||||
for (int i = nums[0]; i <= half; i++) {
|
||||
dp[0][i] = nums[0];
|
||||
}
|
||||
|
||||
// dp[i][j] 表示 放入物品i后,容量为j的背包的最大价值
|
||||
for (int i = 1; i < length; i++) {
|
||||
for (int j = 1; j <= half; j++) {
|
||||
// 放的下
|
||||
if (j >= nums[i]) {
|
||||
dp[i][j] = Math.max(
|
||||
dp[i - 1][j],
|
||||
dp[i - 1][j - nums[i]] + nums[i]
|
||||
);
|
||||
}else {
|
||||
dp[i][j] = dp[i - 1][j];
|
||||
}
|
||||
// 放不下
|
||||
if (dp[i][j] == half) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class Solution1 {
|
||||
/**
|
||||
* 将nums的元素放入背包中
|
||||
* 1. 背包容量 sum/2
|
||||
* 2. 物品i重量nums[i];价值nums[i]
|
||||
*
|
||||
* 0 1 2 3 4 5
|
||||
* 0
|
||||
* 1
|
||||
* 2
|
||||
*
|
||||
* dp[j]表示 j背包容量的最大价值
|
||||
*
|
||||
*
|
||||
*
|
||||
* // 递推公式
|
||||
* 2. 放下 dp[j] = max(dp[j], dp[j-weight[i]]+nums[i])
|
||||
*
|
||||
* 从后往前循环,每次取得状态不会和之前取得状态重合,这样每种物品就只取一次了。
|
||||
*
|
||||
* @param nums
|
||||
* @return
|
||||
*/
|
||||
public boolean canPartition(int[] nums) {
|
||||
|
||||
int sum = 0;
|
||||
for (int num : nums) {
|
||||
sum += num;
|
||||
}
|
||||
|
||||
if (sum % 2 != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 包裹最大容量
|
||||
int packageCapacity = sum / 2;
|
||||
|
||||
int[] dp = new int[packageCapacity + 1];
|
||||
|
||||
for (int i = 0; i < nums.length; i++) {
|
||||
// 包的容量必须大于物品i重量才能放进去
|
||||
/**
|
||||
* 如果正序遍历
|
||||
* dp[1] = dp[1 - weight[0]] + value[0] = 15
|
||||
* 此时容量1的背包已经放入了
|
||||
* dp[2] = dp[2 - weight[0]] + value[0] = 30
|
||||
* 此时又放入了一次
|
||||
*/
|
||||
for (int j = packageCapacity; j >= nums[i]; j--) {
|
||||
dp[j] = Math.max(dp[j], dp[j - nums[i]] + nums[i]);
|
||||
//剪枝一下,每一次完成內層的for-loop,立即檢查是否dp[target] == target,優化時間複雜度(26ms -> 20ms)
|
||||
if(dp[packageCapacity] == packageCapacity)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// 包裹容量和目标值一样
|
||||
return dp[packageCapacity] == packageCapacity;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user