mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-09 03:34:02 +08:00
Merge pull request #39 from nanhuaibeian/master
添加0039.组合总和/0040.组合总和II /0045.跳跃游戏II /0055.跳跃游戏/0322.零钱兑换 /0377.组合总和IV /0383.赎金信 /0416.分割等和子集 /0454.四数相加 /0474.一和零 /0518.零钱兑换II /0707.设计链表/0746.使用最小花费爬楼梯 Java版本
This commit is contained in:
@ -236,7 +236,39 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
Java:
|
Java:
|
||||||
|
```Java
|
||||||
|
class Solution {
|
||||||
|
List<List<Integer>> lists = new ArrayList<>();
|
||||||
|
Deque<Integer> deque = new LinkedList<>();
|
||||||
|
|
||||||
|
public List<List<Integer>> combinationSum3(int k, int n) {
|
||||||
|
int[] arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
|
backTracking(arr, n, k, 0);
|
||||||
|
return lists;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void backTracking(int[] arr, int n, int k, int startIndex) {
|
||||||
|
//如果 n 小于0,没必要继续本次递归,已经不符合要求了
|
||||||
|
if (n < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (deque.size() == k) {
|
||||||
|
if (n == 0) {
|
||||||
|
lists.add(new ArrayList(deque));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i = startIndex; i < arr.length - (k - deque.size()) + 1; i++) {
|
||||||
|
deque.push(arr[i]);
|
||||||
|
//减去当前元素
|
||||||
|
n -= arr[i];
|
||||||
|
backTracking(arr, n, k, i + 1);
|
||||||
|
//恢复n
|
||||||
|
n += deque.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
|
@ -255,7 +255,43 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
Java:
|
Java:
|
||||||
|
```Java
|
||||||
|
class Solution {
|
||||||
|
List<List<Integer>> lists = new ArrayList<>();
|
||||||
|
Deque<Integer> deque = new LinkedList<>();
|
||||||
|
int sum = 0;
|
||||||
|
|
||||||
|
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
|
||||||
|
//为了将重复的数字都放到一起,所以先进行排序
|
||||||
|
Arrays.sort(candidates);
|
||||||
|
//加标志数组,用来辅助判断同层节点是否已经遍历
|
||||||
|
boolean[] flag = new boolean[candidates.length];
|
||||||
|
backTracking(candidates, target, 0, flag);
|
||||||
|
return lists;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void backTracking(int[] arr, int target, int index, boolean[] flag) {
|
||||||
|
if (sum == target) {
|
||||||
|
lists.add(new ArrayList(deque));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i = index; i < arr.length && arr[i] + sum <= target; i++) {
|
||||||
|
//出现重复节点,同层的第一个节点已经被访问过,所以直接跳过
|
||||||
|
if (i > 0 && arr[i] == arr[i - 1] && !flag[i - 1]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
flag[i] = true;
|
||||||
|
sum += arr[i];
|
||||||
|
deque.push(arr[i]);
|
||||||
|
//每个节点仅能选择一次,所以从下一位开始
|
||||||
|
backTracking(arr, target, i + 1, flag);
|
||||||
|
int temp = deque.pop();
|
||||||
|
flag[i] = false;
|
||||||
|
sum -= temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
|
@ -143,7 +143,36 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
Java:
|
Java:
|
||||||
|
```Java
|
||||||
|
class Solution {
|
||||||
|
public int jump(int[] nums) {
|
||||||
|
if (nums == null || nums.length == 0 || nums.length == 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//记录跳跃的次数
|
||||||
|
int count=0;
|
||||||
|
//当前的覆盖最大区域
|
||||||
|
int curDistance = 0;
|
||||||
|
//最大的覆盖区域
|
||||||
|
int maxDistance = 0;
|
||||||
|
for (int i = 0; i < nums.length; i++) {
|
||||||
|
//在可覆盖区域内更新最大的覆盖区域
|
||||||
|
maxDistance = Math.max(maxDistance,i+nums[i]);
|
||||||
|
//说明当前一步,再跳一步就到达了末尾
|
||||||
|
if (maxDistance>=nums.length-1){
|
||||||
|
count++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//走到当前覆盖的最大区域时,更新下一步可达的最大区域
|
||||||
|
if (i==curDistance){
|
||||||
|
curDistance = maxDistance;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
|
@ -86,7 +86,25 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
Java:
|
Java:
|
||||||
|
```Java
|
||||||
|
class Solution {
|
||||||
|
public boolean canJump(int[] nums) {
|
||||||
|
if (nums.length == 1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//覆盖范围
|
||||||
|
int coverRange = nums[0];
|
||||||
|
//在覆盖范围内更新最大的覆盖范围
|
||||||
|
for (int i = 0; i <= coverRange; i++) {
|
||||||
|
coverRange = Math.max(coverRange, i + nums[i]);
|
||||||
|
if (coverRange >= nums.length - 1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
|
@ -181,7 +181,31 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
Java:
|
Java:
|
||||||
|
```Java
|
||||||
|
class Solution {
|
||||||
|
public int coinChange(int[] coins, int amount) {
|
||||||
|
int max = Integer.MAX_VALUE;
|
||||||
|
int[] dp = new int[amount + 1];
|
||||||
|
//初始化dp数组为最大值
|
||||||
|
for (int j = 0; j < dp.length; j++) {
|
||||||
|
dp[j] = max;
|
||||||
|
}
|
||||||
|
//当金额为0时需要的硬币数目为0
|
||||||
|
dp[0] = 0;
|
||||||
|
for (int i = 0; i < coins.length; i++) {
|
||||||
|
//正序遍历:完全背包每个硬币可以选择多次
|
||||||
|
for (int j = coins[i]; j <= amount; j++) {
|
||||||
|
//只有dp[j-coins[i]]不是初始最大值时,该位才有选择的必要
|
||||||
|
if (dp[j - coins[i]] != max) {
|
||||||
|
//选择硬币数目最小的情况
|
||||||
|
dp[j] = Math.min(dp[j], dp[j - coins[i]] + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dp[amount] == max ? -1 : dp[amount];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
|
@ -147,7 +147,23 @@ C++测试用例有超过两个树相加超过int的数据,所以需要在if里
|
|||||||
|
|
||||||
|
|
||||||
Java:
|
Java:
|
||||||
|
```Java
|
||||||
|
class Solution {
|
||||||
|
public int combinationSum4(int[] nums, int target) {
|
||||||
|
int[] dp = new int[target + 1];
|
||||||
|
dp[0] = 1;
|
||||||
|
for (int i = 0; i <= target; i++) {
|
||||||
|
for (int j = 0; j < nums.length; j++) {
|
||||||
|
if (i >= nums[j]) {
|
||||||
|
dp[i] += dp[i - nums[j]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dp[target];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
|
@ -111,7 +111,31 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
Java:
|
Java:
|
||||||
|
```Java
|
||||||
|
class Solution {
|
||||||
|
public boolean canConstruct(String ransomNote, String magazine) {
|
||||||
|
//记录杂志字符串出现的次数
|
||||||
|
int[] arr = new int[26];
|
||||||
|
int temp;
|
||||||
|
for (int i = 0; i < magazine.length(); i++) {
|
||||||
|
temp = magazine.charAt(i) - 'a';
|
||||||
|
arr[temp]++;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < ransomNote.length(); i++) {
|
||||||
|
temp = ransomNote.charAt(i) - 'a';
|
||||||
|
//对于金信中的每一个字符都在数组中查找
|
||||||
|
//找到相应位减一,否则找不到返回false
|
||||||
|
if (arr[temp] > 0) {
|
||||||
|
arr[temp]--;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
|
@ -185,7 +185,41 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
Java:
|
Java:
|
||||||
|
```Java
|
||||||
|
class Solution {
|
||||||
|
public boolean canPartition(int[] nums) {
|
||||||
|
int sum = 0;
|
||||||
|
for (int i : nums) {
|
||||||
|
sum += i;
|
||||||
|
}
|
||||||
|
if ((sum & 1) == 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int length = nums.length;
|
||||||
|
int target = sum >> 1;
|
||||||
|
//dp[j]表示前i个元素可以找到相加等于j情况
|
||||||
|
boolean[] dp = new boolean[target + 1];
|
||||||
|
//对于第一个元素,只有当j=nums[0]时,才恰好填充满
|
||||||
|
if (nums[0] <= target) {
|
||||||
|
dp[nums[0]] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i < length; i++) {
|
||||||
|
//j由右往左直到nums[i]
|
||||||
|
for (int j = target; j >= nums[i]; j--) {
|
||||||
|
//只有两种情况,要么放,要么不放
|
||||||
|
//取其中的TRUE值
|
||||||
|
dp[j] = dp[j] || dp[j - nums[i]];
|
||||||
|
}
|
||||||
|
//一旦满足,结束,因为只需要找到一组值即可
|
||||||
|
if (dp[target]) {
|
||||||
|
return dp[target];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dp[target];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
|
@ -88,7 +88,36 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
Java:
|
Java:
|
||||||
|
```Java
|
||||||
|
class Solution {
|
||||||
|
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
|
||||||
|
Map<Integer, Integer> map = new HashMap<>();
|
||||||
|
int temp;
|
||||||
|
int res = 0;
|
||||||
|
//统计两个数组中的元素之和,同时统计出现的次数,放入map
|
||||||
|
for (int i : nums1) {
|
||||||
|
for (int j : nums2) {
|
||||||
|
temp = i + j;
|
||||||
|
if (map.containsKey(temp)) {
|
||||||
|
map.put(temp, map.get(temp) + 1);
|
||||||
|
} else {
|
||||||
|
map.put(temp, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//统计剩余的两个元素的和,在map中找是否存在相加为0的情况,同时记录次数
|
||||||
|
for (int i : nums3) {
|
||||||
|
for (int j : nums4) {
|
||||||
|
temp = i + j;
|
||||||
|
if (map.containsKey(0 - temp)) {
|
||||||
|
res += map.get(0 - temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
|
@ -161,7 +161,33 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
Java:
|
Java:
|
||||||
|
```Java
|
||||||
|
class Solution {
|
||||||
|
public int findMaxForm(String[] strs, int m, int n) {
|
||||||
|
//dp[i][j]表示i个0和j个1时的最大子集
|
||||||
|
int[][] dp = new int[m + 1][n + 1];
|
||||||
|
int oneNum, zeroNum;
|
||||||
|
for (String str : strs) {
|
||||||
|
oneNum = 0;
|
||||||
|
zeroNum = 0;
|
||||||
|
for (char ch : str.toCharArray()) {
|
||||||
|
if (ch == '0') {
|
||||||
|
zeroNum++;
|
||||||
|
} else {
|
||||||
|
oneNum++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//倒序遍历
|
||||||
|
for (int i = m; i >= zeroNum; i--) {
|
||||||
|
for (int j = n; j >= oneNum; j--) {
|
||||||
|
dp[i][j] = Math.max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dp[m][n];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
|
@ -188,7 +188,22 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
Java:
|
Java:
|
||||||
|
```Java
|
||||||
|
class Solution {
|
||||||
|
public int change(int amount, int[] coins) {
|
||||||
|
//递推表达式
|
||||||
|
int[] dp = new int[amount + 1];
|
||||||
|
//初始化dp数组,表示金额为0时只有一种情况,也就是什么都不装
|
||||||
|
dp[0] = 1;
|
||||||
|
for (int i = 0; i < coins.length; i++) {
|
||||||
|
for (int j = coins[i]; j <= amount; j++) {
|
||||||
|
dp[j] += dp[j - coins[i]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dp[amount];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
|
@ -157,7 +157,78 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
Java:
|
Java:
|
||||||
|
```Java
|
||||||
|
class MyLinkedList {
|
||||||
|
//size存储链表元素的个数
|
||||||
|
int size;
|
||||||
|
//虚拟头结点
|
||||||
|
ListNode head;
|
||||||
|
|
||||||
|
//初始化链表
|
||||||
|
public MyLinkedList() {
|
||||||
|
size = 0;
|
||||||
|
head = new ListNode(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取第index个节点的数值
|
||||||
|
public int get(int index) {
|
||||||
|
//如果index非法,返回-1
|
||||||
|
if (index < 0 || index >= size) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ListNode currentNode = head;
|
||||||
|
//包含一个虚拟头节点,所以查找第 index+1 个节点
|
||||||
|
for (int i = 0; i <= index; i++) {
|
||||||
|
currentNode = currentNode.next;
|
||||||
|
}
|
||||||
|
return currentNode.val;
|
||||||
|
}
|
||||||
|
|
||||||
|
//在链表最前面插入一个节点
|
||||||
|
public void addAtHead(int val) {
|
||||||
|
addAtIndex(0, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
//在链表的最后插入一个节点
|
||||||
|
public void addAtTail(int val) {
|
||||||
|
addAtIndex(size, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在第 index 个节点之前插入一个新节点,例如index为0,那么新插入的节点为链表的新头节点。
|
||||||
|
// 如果 index 等于链表的长度,则说明是新插入的节点为链表的尾结点
|
||||||
|
// 如果 index 大于链表的长度,则返回空
|
||||||
|
public void addAtIndex(int index, int val) {
|
||||||
|
if (index > size) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (index < 0) {
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
size++;
|
||||||
|
//找到要插入节点的前驱
|
||||||
|
ListNode pred = head;
|
||||||
|
for (int i = 0; i < index; i++) {
|
||||||
|
pred = pred.next;
|
||||||
|
}
|
||||||
|
ListNode toAdd = new ListNode(val);
|
||||||
|
toAdd.next = pred.next;
|
||||||
|
pred.next = toAdd;
|
||||||
|
}
|
||||||
|
|
||||||
|
//删除第index个节点
|
||||||
|
public void deleteAtIndex(int index) {
|
||||||
|
if (index < 0 || index >= size) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
size--;
|
||||||
|
ListNode pred = head;
|
||||||
|
for (int i = 0; i < index; i++) {
|
||||||
|
pred = pred.next;
|
||||||
|
}
|
||||||
|
pred.next = pred.next.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
|
@ -203,7 +203,26 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
Java:
|
Java:
|
||||||
|
```Java
|
||||||
|
class Solution {
|
||||||
|
public int minCostClimbingStairs(int[] cost) {
|
||||||
|
if (cost == null || cost.length == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (cost.length == 1) {
|
||||||
|
return cost[0];
|
||||||
|
}
|
||||||
|
int[] dp = new int[cost.length];
|
||||||
|
dp[0] = cost[0];
|
||||||
|
dp[1] = cost[1];
|
||||||
|
for (int i = 2; i < cost.length; i++) {
|
||||||
|
dp[i] = Math.min(dp[i - 1], dp[i - 2]) + cost[i];
|
||||||
|
}
|
||||||
|
//最后一步,如果是由倒数第二步爬,则最后一步的体力花费可以不用算
|
||||||
|
return Math.min(dp[cost.length - 1], dp[cost.length - 2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user