feat(leetcode): 添加新的算法题目实现

- 实现LeetCode322 题目:零钱兑换。提供了一个Solution类,使用动态规划算法计算最少的硬币数量。
- 实现LeetCode 377 题目:组合总和IV。提供了一个Solution类,使用动态规划算法计算组合的总数。
- 实现LeetCode 快速排序。提供了一个Solution类,包含一个快速排序算法,能够对数组进行排序。各题目实现均通过测试验证。
This commit is contained in:
whaifree 2024-08-22 00:43:33 +08:00
parent 1acabb1909
commit 8f722ebb0c
3 changed files with 170 additions and 0 deletions

View File

@ -0,0 +1,54 @@
package cn.whaifree.redo.redoAll;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/8/21 23:53
* @注释
*/
public class LeetCode322 {
@Test
public void test() {
int[] coins = {2};
int amount = 3;
Solution solution = new Solution();
int i = solution.coinChange(coins, amount);
System.out.println(i);
}
class Solution {
/**
* dp[j] 表示从0-i中随便取满足j个背包容量的最少个数
*
* 0 1 2 3 4 5 6 7 8 9 10 11
* 1 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11]
* 2 [0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6]
* 5 [0, 1, 1, 2, 2, 1, 2, 2, 3, 3, 2, 3]
*
* @param coins
* @param amount
* @return
*/
public int coinChange(int[] coins, int amount) {
int[] dp = new int[amount + 1];
for (int i = 1; i <= amount; i++) {
dp[i] = Integer.MAX_VALUE;
}
dp[0] = 0;
for (int i = 0; i < coins.length; i++) {
for (int j = coins[i]; j <= amount; j++) {
if (dp[j - coins[i]] != Integer.MAX_VALUE) {
dp[j] = Math.min(dp[j], dp[j - coins[i]] + 1);
}
}
}
return dp[amount] == Integer.MAX_VALUE ? -1 : dp[amount];
}
}
}

View File

@ -0,0 +1,59 @@
package cn.whaifree.redo.redoAll;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/8/22 0:14
* @注释
*/
public class LeetCode377 {
@Test
public void test() {
int[] nums = {1, 2, 3};
int target = 4;
Solution solution = new Solution();
System.out.println(solution.combinationSum4(nums, target));
}
class Solution {
/**
* dp[i] 表示
*
* @param nums
* @param target
* @return
*/
public int combinationSum4(int[] nums, int target) {
/**
* 如果我们先遍历物品nums再遍历背包target那么我们实际上是在考虑每个物品对每个目标值的贡献
* 这种方式会忽略组合的顺序即它只考虑了物品的组合而不考虑这些物品的排列顺序
* - 确定一个物品就不会关注他的顺序
*
* 例如对于目标值4如果我们先遍历物品
* 可能会得到组合{1,3}但不会得到组合{3,1}因为这种方式只考虑了物品的组合而不考虑排列
*/
int[] dp = new int[target + 1];
dp[0] = 1; // 都不放入 情况有一种
for (int j = 1; j < target + 1; j++) {
for (int i = 0; i < nums.length; i++) {
if (j >= nums[i]) {
dp[j] = dp[j] + dp[j - nums[i]];
// dp[j] 不放
// dp[j - nums[i]] 放也有多种情况
}
}
/**
* 如果把遍历nums物品放在外循环
* 遍历target的作为内循环的话举一个例子
* 计算dp[4]的时候结果集只有 {1,3} 这样的集合忽略了{3,1}
*/
}
return dp[target];
}
}
}

View File

@ -0,0 +1,57 @@
package cn.whaifree.redo.redoAll;
import java.util.Arrays;
import java.util.Random;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/8/21 22:30
* @注释
*/
public class LeetCodeQuickSort {
public static void main(String[] args) {
System.out.println(Arrays.toString(new LeetCodeQuickSort().new Solution().sortArray(new int[]{110, 100, 0})));
}
class Solution {
public int[] sortArray(int[] nums) {
sort(nums, 0, nums.length - 1);
return nums;
}
public static void sort(int[] nums, int leftIndex, int rightIndex) {
if (leftIndex >= rightIndex) {
return;
}
// ! 随机挑选一个幸运儿
int q = new Random().nextInt(rightIndex - leftIndex + 1) + leftIndex;
swap(nums, leftIndex, q);
int pivot = nums[leftIndex];
int l = leftIndex;
int r = rightIndex;
while (l < r) {
while (l < r && nums[r] >= pivot) {
r--;
}
while (l < r && nums[l] <= pivot) {
l++;
}
swap(nums, l, r);
}
swap(nums, l, leftIndex);
sort(nums, leftIndex, l - 1);
sort(nums, r + 1, rightIndex);
}
public static void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
}