添加了23、32、503、739、24个测试用例,优化了188题的代码,并添加了线程测试类ThreadTest和LeetCode123的测试用例。

This commit is contained in:
whaifree 2024-04-14 11:58:15 +08:00
parent 0cbd5b4619
commit 7ed697d929
12 changed files with 852 additions and 13 deletions

View File

@ -15,31 +15,49 @@ public class Stock {
@Test @Test
public void test() public void test()
{ {
// int[] prices = {7,1,5,3,6,4}; System.out.println(new LeetCode188_.Solution().maxProfit(2, new int[]{3,2,6,5,0,3}));
int[] prices = {1,2,3,4,5};
System.out.println(new LeetCode123_.Solution().maxProfit(prices));
} }
} }
class LeetCode188_{ class LeetCode188_{
class Solution { static class Solution {
public int maxProfit(int k, int[] prices) { public int maxProfit(int k, int[] prices) {
// dp[i][j] 表示第i天交易第k次的最大收益 // dp[i][j] 表示第i天交易第k次的最大收益
// dp[i][0] 表示第i天第 0/2 +1 次持有的最大手头 // dp[i][1] 表示第i天第 1/2 +1 次持有的最大手头
// dp[i][1] 表示第i天第 1/2 +1次未持有的最大手头 // dp[i][0] 表示第i天第 0/2 +1次未持有的最大手头
int[][] dp = new int[prices.length][k * 2]; // dp[i][0] = max dp[i-1][0] dp[i-1][1]+prices[i]
// dp[i][1] = max dp[i-1][1] dp[i-1][0]-prices[i]
// dp[i][2] = max dp[i-1][2] dp[i-1][1]+prices[i]
// dp[i][3] = max dp[i-1][3] dp[i-1][2]-prices[i]
int[][] dp = new int[prices.length][k * 2 + 1];
// 未持有 初始化 // 未持有 初始化
for (int i = 0; i < prices.length; i += 2) { for (int i = 1; i <= k * 2; i += 2) {
dp[i][0] = -prices[0]; dp[0][i] = -prices[0];
} }
for (int i = 0; i < prices.length; i++) { for (int i = 1; i < prices.length; i++) {
for (int j = 0; j < k * 2; j++) { for (int j = 0; j < k ; j++) {
int indexJ = 2 * j + 1;
dp[i][indexJ] = Math.max(dp[i - 1][indexJ], dp[i - 1][indexJ - 1] - prices[i]);
dp[i][indexJ + 1] = Math.max(dp[i - 1][indexJ + 1], dp[i - 1][indexJ] + prices[i]);
}
}
return dp[prices.length - 1][k * 2];
} // 假设k=2
} // int[][] dp = new int[prices.length][5];
return 1; // // 4种状态 1 3 表示持有
// dp[0][1] = -prices[0];
// dp[0][3] = -prices[0];
// for (int i = 1; i < prices.length; i++) {
// dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
// dp[i][2] = Math.max(dp[i - 1][2], dp[i - 1][1] + prices[i]);
// dp[i][3] = Math.max(dp[i - 1][3], dp[i - 1][2] - prices[i]);
// dp[i][4] = Math.max(dp[i - 1][4], dp[i - 1][3] + prices[i]);
// }
// return dp[prices.length - 1][4];
} }
} }
} }

View File

@ -0,0 +1,30 @@
package cn.whaifree.leetCode.LinkedList;
import cn.whaifree.leetCode.model.ListNode;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/4/13 11:06
* @注释
*/
public class LeetCode160 {
@Test
public void test()
{
}
class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode A = headA, B = headB;
while (A != B) {
A = A == null ? headB : A.next;
B = B == null ? headA : B.next;
}
return A;
}
}
}

View File

@ -0,0 +1,64 @@
package cn.whaifree.redo.redo_24_4_13;
import cn.whaifree.leetCode.model.ListNode;
import org.junit.Test;
import java.util.Comparator;
import java.util.PriorityQueue;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/4/13 13:49
* @注释
*/
public class LeetCode23 {
@Test
public void test() {
new Solution().mergeKLists(
new ListNode[]{
ListNode.listNodeFromArray(new int[]{1, 4, 5})
, ListNode.listNodeFromArray(new int[]{1, 3, 4})
, ListNode.listNodeFromArray(new int[]{2, 6})
}
).printList();
}
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
// 优先队列
PriorityQueue<ListNode> queue = new PriorityQueue<>(
new Comparator<ListNode>() {
@Override
public int compare(ListNode o1, ListNode o2) {
return o1.val - o2.val;
}
}
);
// 优先队列内出来就是最大的头部
for (ListNode list : lists) {
if (list != null) {
queue.add(list);
}
}
ListNode pre = new ListNode(-1);
ListNode preIndex = pre;
while (!queue.isEmpty()) {
ListNode poll = queue.poll();
preIndex.next = poll;
preIndex = preIndex.next;
if (poll.next != null) {
queue.add(poll.next);
}
}
return pre.next;
}
}
}

View File

@ -0,0 +1,102 @@
package cn.whaifree.redo.redo_24_4_13;
import org.junit.Test;
import java.util.Deque;
import java.util.LinkedList;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/4/13 14:14
* @注释
*/
public class LeetCode32 {
@Test
public void test()
{
Solution solution = new Solution();
int i = solution.longestValidParentheses("()(()");
System.out.println(i);
}
class Solution {
public int longestValidParentheses(String s) {
/**
* 找到匹配
* 最长
*/
boolean[] flag = new boolean[s.length()];
Deque<Integer> stack = new LinkedList<>();
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(') {
stack.push(i);
}else if (!stack.isEmpty()) {
flag[stack.pop()] = true;
flag[i] = true;
}
}
// 统计flag连续出现的
int longMax = 0;
int flagIndex = 0;
for (int i = 0; i < flag.length; i++) {
if (flag[i]) {
flagIndex++;
}else {
flagIndex = 0;
}
longMax = Math.max(longMax, flagIndex);
}
return longMax;
}
}
class Solution1 {
/**
* 计数器
* 计算左括号右括号的数量如果右括号数量更多就重置
* @param s
* @return
*/
public int longestValidParentheses(String s) {
int left = 0, right = 0, maxlength = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(') {
left++;
}else if (s.charAt(i) == ')') {
right++;
}
if (right > left) {
left = 0;
right = 0;
}
if (right == left) {
maxlength = Math.max(maxlength, 2 * left);
}
}
left = 0;
right = 0;
for (int i = s.length() - 1; i >= 0; i--) {
if (s.charAt(i) == '(') {
left++;
}else if (s.charAt(i) == ')') {
right++;
}
if (left > right) {
left = 0;
right = 0;
}
if (left == right) {
maxlength = Math.max(maxlength, 2 * right);
}
}
return maxlength;
}
}
}

View File

@ -0,0 +1,10 @@
package cn.whaifree.redo.redo_24_4_13;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/4/14 11:55
* @注释
*/
public class LeetCode337 {
}

View File

@ -0,0 +1,80 @@
package cn.whaifree.redo.redo_24_4_13;
import org.junit.Test;
import java.util.Deque;
import java.util.LinkedList;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/4/13 11:10
* @注释
*/
public class LeetCode42 {
@Test
public void test()
{
int[] height = {0,1,0,2,1,0,1,3,2,1,2,1};
System.out.println(new Solution1().trap(height));
}
class Solution {
public int trap(int[] height) {
// 接下雨水寻找凹陷处
Deque<Integer> stack = new LinkedList<>();
/* int[] he = new int[height.length + 2];
for (int i = 1; i < height.length + 1; i++) {
he[i] = height[i - 1];
}
height = he;*/
stack.push(0);
int res = 0;
for (int i = 0; i < height.length; i++) {
if (height[stack.peek()] < height[i]) {
while (!stack.isEmpty()&&height[stack.peek()] < height[i]) {
int mid = stack.pop();
if (!stack.isEmpty()) {
int right = i;
int left = stack.peek();
int w = right - left - 1;
int h = (Math.min(height[left], height[right]) - height[mid]);
res += w * h;
}
}
stack.push(i);
}else {
stack.push(i);
}
}
return res;
}
}
class Solution1 {
public int trap(int[] height) {
int[] left = new int[height.length];
int[] right = new int[height.length];
// 从左到右获取左边左边最小
int max = Integer.MIN_VALUE;
for (int i = 0; i < height.length; i++) {
max = Math.max(max, height[i]);
left[i] = max;
}
max = Integer.MIN_VALUE;
for (int i = height.length - 1; i >= 0; i--) {
max = Math.max(max, height[i]);
right[i] = max;
}
int res = 0;
for (int i = 0; i < height.length; i++) {
res += (Math.min(left[i], right[i]) - height[i]);
}
return res;
}
}
}

View File

@ -0,0 +1,55 @@
package cn.whaifree.redo.redo_24_4_13;
import org.junit.Test;
import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/4/13 13:05
* @注释
*/
public class LeetCode496 {
@Test
public void test()
{
int[] nums1 = {4,1,2};
int[] nums2 = {1,3,4,2};
int[] res = new Solution().nextGreaterElement(nums1, nums2);
for (int i : res) {
System.out.println(i);
}
}
class Solution {
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
// nums1对应位置的下一个更大元素
Map<Integer, Integer> map = new HashMap<>();
Deque<Integer> stack = new LinkedList<>();
stack.push(nums2[0]);
for (int i = 1; i < nums2.length; i++) {
while (!stack.isEmpty() && nums2[i] > stack.peek()) {
map.put(stack.pop(), nums2[i]);
}
stack.push(nums2[i]);
}
int[] res = new int[nums1.length];
for (int i = 0; i < nums1.length; i++) {
int key = nums1[i];
if (map.containsKey(key)) {
res[i] = map.get(key);
} else {
res[i] = -1;
}
}
return res;
}
}
}

View File

@ -0,0 +1,45 @@
package cn.whaifree.redo.redo_24_4_13;
import org.junit.Test;
import java.util.Arrays;
import java.util.Deque;
import java.util.LinkedList;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/4/13 13:29
* @注释
*/
public class LeetCode503 {
@Test
public void test()
{
int[] nums = new int[]{1,2,3,4,3};
Solution solution = new Solution();
int[] res = solution.nextGreaterElements(nums);
for (int i : res) {
System.out.println(i);
}
}
class Solution {
public int[] nextGreaterElements(int[] nums) {
Deque<Integer> stack = new LinkedList<>();
stack.push(0);
int[] res = new int[nums.length];
Arrays.fill(res, -1);
int len = nums.length;
int length = len * 2;
for (int i = 1; i < length; i++) {
while (!stack.isEmpty() && nums[i % len] > nums[stack.peek()]) {
res[stack.pop()] = nums[i % len];
}
stack.push(i % len);
}
return res;
}
}
}

View File

@ -0,0 +1,43 @@
package cn.whaifree.redo.redo_24_4_13;
import org.junit.Test;
import java.util.Deque;
import java.util.LinkedList;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/4/13 13:37
* @注释
*/
public class LeetCode739 {
@Test
public void test()
{
int[] temperatures = {73, 74, 75, 71, 69, 72, 76, 73};
int[] ints = new Solution().dailyTemperatures(temperatures);
for (int anInt : ints) {
System.out.println(anInt);
}
}
// 下一个更高温度出现在几天后
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
int[] ans = new int[temperatures.length];
Deque<Integer> stack = new LinkedList<>();
stack.push(0);
for (int i = 1; i < temperatures.length; i++) {
while (!stack.isEmpty() && temperatures[stack.peek()] < temperatures[i]) {
Integer pop = stack.pop();
ans[pop] = i - pop;
}
stack.push(i);
}
return ans;
}
}
}

View File

@ -0,0 +1,88 @@
package cn.whaifree.redo.redo_24_4_13;
import org.junit.Test;
import java.util.Deque;
import java.util.LinkedList;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/4/13 11:43
* @注释
*/
public class LeetCode84 {
@Test
public void test()
{
int[] heights = {2,1,5,6,2,3};
int i = new Solution1().largestRectangleArea(heights);
System.out.println(i);
}
class Solution {
public int largestRectangleArea(int[] heights) {
int[] he = new int[heights.length + 2];
System.arraycopy(heights, 0, he, 1, heights.length);
heights = he;
Deque<Integer> stack = new LinkedList<>();
// 找到凸点
stack.push(0);
int maxR = 0;
for (int i = 1; i < heights.length; i++) {
if (heights[i] < heights[stack.peek()]) {
while (!stack.isEmpty() && heights[i] < heights[stack.peek()]) {
// 找到下坡后挨个弹出栈这个出栈位置的就是高判断新的面积会不会更大
int mid = stack.pop();
if (!stack.isEmpty()) {
int left = stack.peek();
int right = i;
int h = heights[mid];
maxR = Math.max(maxR, (right - left - 1) * h);
}
}
}
stack.push(i);
}
return maxR;
}
}
class Solution1 {
public int largestRectangleArea(int[] heights) {
// 每个记录左边第一个小于本身的位置
int[] left = new int[heights.length];
int[] right = new int[heights.length];
left[0] = -1;
for (int i = 1; i < heights.length; i++) {
int index = i - 1;
while (index >= 0 && heights[index] >= heights[i]) {
index = left[index];
}
left[i] = index;
}
// 每个记录右边边第一个小于本身的位置
right[heights.length - 1] = heights.length;
for (int i = heights.length - 2; i >= 0; i--) {
int index = i + 1;
while (index <= heights.length - 1 && heights[index] >= heights[i]) {
index = right[index];
}
right[i] = index;
}
int maxD = 0;
for (int i = 0; i < heights.length; i++) {
int leftIndex = left[i];
int rightIndex = right[i];
maxD = Math.max(maxD, (rightIndex - leftIndex - 1) * heights[i]);
}
return maxD;
}
}
}

View File

@ -1,6 +1,8 @@
package cn.whaifree.test; package cn.whaifree.test;
public class ThreadLocalExample { public class ThreadLocalExample {
// 使用Lambda表达式与withInitial()方法指定初始值
private static final ThreadLocal<String> threadLocal = ThreadLocal.withInitial(() -> "Default Value from Lambda");
public static void main(String[] args) throws InterruptedException { public static void main(String[] args) throws InterruptedException {
for(int i=0 ; i<3; i++){ for(int i=0 ; i<3; i++){

View File

@ -0,0 +1,302 @@
package cn.whaifree.test;
import java.util.concurrent.Semaphore;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/4/13 16:06
* @注释
*/
public class ThreadTest {
private static Object lock = new Object();
private static Integer count = 0;
/**
* 主函数示例演示了通过两个线程交替打印字符并控制其执行顺序的简单并发程序
* 使用一个共享计数器和一个对象锁来协调两个线程的执行
* 线程1打印字符'a'线程2打印字符'b'交替进行直到计数器达到100
*
* @param args 命令行参数未使用
* @throws InterruptedException 如果线程在等待时被中断则抛出此异常
*/
public static void main1(String[] args) throws InterruptedException{
// 启动线程1负责打印'a'并进行同步控制
new Thread(
new Runnable() {
@Override
public void run() {
while (count < 100) {
synchronized (lock) {
// 当计数器为偶数时线程1等待
if (count % 2 == 0) {
try {
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("a");
count++;
// 计数器为奇数时唤醒等待的线程2
lock.notify();
}
}
}
}
).start();
// 启动线程2负责打印'b'并进行同步控制
new Thread(
new Runnable() {
@Override
public void run() {
while (count < 100) {
synchronized (lock) {
// 当计数器为奇数时线程2等待
if (count % 2 != 0) {
try {
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("b");
count++;
// 计数器为偶数时唤醒等待的线程1
lock.notify();
}
}
}
}
).start();
}
public static void main3(String[] args) throws InterruptedException{
// 创建三个线程
Thread threadA = new Thread(() -> {
try {
// 循环100次
for (int i = 0; i < 100; i++) {
// 获取锁
synchronized (lock) {
// 判断是否轮到自己执行
while (count % 3 != 0) {
// 不是则等待
lock.wait();
}
// 打印字母
System.out.println("A");
// 修改状态
count++;
// 唤醒下一个线程
lock.notifyAll();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread threadB = new Thread(() -> {
try {
for (int i = 0; i < 100; i++) {
synchronized (lock) {
while (count % 3 != 1) {
lock.wait();
}
System.out.println("B");
count++;
lock.notifyAll();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread threadC = new Thread(() -> {
try {
for (int i = 0; i < 100; i++) {
synchronized (lock) {
// 确保严格到本线程打的时候再等候
while (count % 3 != 2) {
lock.wait();
}
System.out.println("C");
count++;
lock.notifyAll();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// 启动三个线程
threadA.start();
threadB.start();
threadC.start();
}
private static final Semaphore semaphoreC = new Semaphore(2); // 初始化为0表示开始时阻止线程2打印'b'执行
private static final Semaphore semaphoreA = new Semaphore(1); // 初始化为1表示开始时允许线程1打印'a'执行
private static final Semaphore semaphoreB = new Semaphore(0); // 初始化为0表示开始时阻止线程2打印'b'执行
public static void main2(String[] args) throws InterruptedException {
new Thread(
() -> {
for (int i = 0; i < 50; i++) {
try {
semaphoreA.acquire();
System.out.println("a");
semaphoreB.release();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
).start();
new Thread(
() -> {
for (int i = 0; i < 50; i++) {
try {
semaphoreB.acquire();
System.out.println("b");
semaphoreA.release();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
).start();
}
// public static void main(String[] args) throws InterruptedException{
//
// new Thread(
// new Runnable() {
// @Override
// public void run() {
// while (count < 100) {
// synchronized (count) {
// System.out.println(count);
// if (count % 2 == 0) {
// try {
// count.wait();
// } catch (InterruptedException e) {
// throw new RuntimeException(e);
// }
// }
// System.out.println("a");
// count++;
// count.notify();
// }
// }
// }
// }
// ).start();
// new Thread(
// new Runnable() {
// @Override
// public void run() {
// while (count < 100) {
// synchronized (count) {
// System.out.println(count);
// if (count % 2 != 0) {
// try {
// count.wait(); // 此时就释放锁了
//
// } catch (InterruptedException e) {
// throw new RuntimeException(e);
// }
// }
//
// System.out.println("b");
// count++;
// count.notify();
// }
// }
// }
// }
// ).start();
//
//
// }
public static void main(String[] args) {
new Thread(
() -> {
while (count < 100) {
while (count % 3 == 0) {
System.out.println("A");
count++;
}
}
}
).start();
new Thread(
() -> {
while (count < 100) {
while (count % 3 == 1) {
System.out.println("B");
count++;
}
}
}
).start();
new Thread(
() -> {
while (count < 100) {
while (count % 3 == 2) {
System.out.println("C");
count++;
}
}
}
).start();
}
}
class DidLock{
public static void main(String[] args) {
Object a = new Object();
Object b = new Object();
new Thread(
()->{
synchronized (a) {
try {
System.out.println(Thread.currentThread().getName() + "a");
Thread.sleep(100);
synchronized (b) {
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
).start();
new Thread(
()->{
synchronized (b) {
System.out.println(Thread.currentThread().getName() + "b");
synchronized (a) {
}
}
}
).start();
}
}