mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-06 23:28:29 +08:00
Update
This commit is contained in:
@ -42,7 +42,8 @@
|
||||
|
||||
我以[1,2,3]为例,抽象成树形结构如下:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
### 回溯三部曲
|
||||
|
||||
@ -54,7 +55,7 @@
|
||||
|
||||
但排列问题需要一个used数组,标记已经选择的元素,如图橘黄色部分所示:
|
||||
|
||||

|
||||

|
||||
|
||||
代码如下:
|
||||
|
||||
@ -66,7 +67,7 @@ void backtracking (vector<int>& nums, vector<bool>& used)
|
||||
|
||||
* 递归终止条件
|
||||
|
||||

|
||||

|
||||
|
||||
可以看出叶子节点,就是收割结果的地方。
|
||||
|
||||
|
@ -134,17 +134,17 @@ x = (target + sum) / 2
|
||||
|
||||
大家看到(target + sum) / 2 应该担心计算的过程中向下取整有没有影响。
|
||||
|
||||
这么担心就对了,例如sum 是5,S是2的话其实就是无解的,所以:
|
||||
这么担心就对了,例如sum是5,target是2 的话其实就是无解的,所以:
|
||||
|
||||
```CPP
|
||||
(C++代码中,输入的S 就是题目描述的 target)
|
||||
if ((S + sum) % 2 == 1) return 0; // 此时没有方案
|
||||
if ((target + sum) % 2 == 1) return 0; // 此时没有方案
|
||||
```
|
||||
|
||||
同时如果 S的绝对值已经大于sum,那么也是没有方案的。
|
||||
同时如果target 的绝对值已经大于sum,那么也是没有方案的。
|
||||
|
||||
```CPP
|
||||
(C++代码中,输入的S 就是题目描述的 target)
|
||||
if (abs(S) > sum) return 0; // 此时没有方案
|
||||
if (abs(target) > sum) return 0; // 此时没有方案
|
||||
```
|
||||
|
||||
再回归到01背包问题,为什么是01背包呢?
|
||||
@ -213,9 +213,9 @@ dp[j]其他下标对应的数值也应该初始化为0,从递推公式也可
|
||||
|
||||
5. 举例推导dp数组
|
||||
|
||||
输入:nums: [1, 1, 1, 1, 1], S: 3
|
||||
输入:nums: [1, 1, 1, 1, 1], target: 3
|
||||
|
||||
bagSize = (S + sum) / 2 = (3 + 5) / 2 = 4
|
||||
bagSize = (target + sum) / 2 = (3 + 5) / 2 = 4
|
||||
|
||||
dp数组状态变化如下:
|
||||
|
||||
@ -226,12 +226,12 @@ C++代码如下:
|
||||
```CPP
|
||||
class Solution {
|
||||
public:
|
||||
int findTargetSumWays(vector<int>& nums, int S) {
|
||||
int findTargetSumWays(vector<int>& nums, int target) {
|
||||
int sum = 0;
|
||||
for (int i = 0; i < nums.size(); i++) sum += nums[i];
|
||||
if (abs(S) > sum) return 0; // 此时没有方案
|
||||
if ((S + sum) % 2 == 1) return 0; // 此时没有方案
|
||||
int bagSize = (S + sum) / 2;
|
||||
if (abs(target) > sum) return 0; // 此时没有方案
|
||||
if ((target + sum) % 2 == 1) return 0; // 此时没有方案
|
||||
int bagSize = (target + sum) / 2;
|
||||
vector<int> dp(bagSize + 1, 0);
|
||||
dp[0] = 1;
|
||||
for (int i = 0; i < nums.size(); i++) {
|
||||
@ -655,3 +655,52 @@ public class Solution
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
||||
class Solution {
|
||||
public:
|
||||
int findTargetSumWays(vector<int>& nums, int target) {
|
||||
int sum = 0;
|
||||
for (int i = 0; i < nums.size(); i++) sum += nums[i];
|
||||
if (abs(target) > sum) return 0; // 此时没有方案
|
||||
if ((target + sum) % 2 == 1) return 0; // 此时没有方案
|
||||
int bagSize = (target + sum) / 2;
|
||||
|
||||
vector<vector<int>> dp(nums.size(), vector<int>(bagSize + 1, 0));
|
||||
|
||||
if (nums[0] <= bagSize) dp[0][nums[0]] = 1;
|
||||
|
||||
dp[0][0] = 1;
|
||||
|
||||
int numZero = 0;
|
||||
for (int i = 0; i < nums.size(); i++) {
|
||||
if (nums[i] == 0) numZero++;
|
||||
dp[i][0] = (int) pow(2.0, numZero);
|
||||
}
|
||||
|
||||
for (int i = 1; i < nums.size(); i++) {
|
||||
for (int j = 0; j <= bagSize; j++) {
|
||||
if (nums[i] > j) dp[i][j] = dp[i - 1][j];
|
||||
else dp[i][j] = dp[i - 1][j] + dp[i - 1][j - nums[i]];
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < nums.size(); i++) {
|
||||
for (int j = 0; j <= bagSize; j++) {
|
||||
cout << dp[i][j] << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
return dp[nums.size() - 1][bagSize];
|
||||
}
|
||||
};
|
||||
|
||||
1 1 0 0 0
|
||||
1 2 1 0 0
|
||||
1 3 3 1 0
|
||||
1 4 6 4 1
|
||||
1 5 10 10 5
|
||||
|
||||
初始化 如果没有0, dp[i][0] = 1; 即所有元素都不取。
|
||||
|
||||
用元素 取与不取来举例
|
||||
|
||||
|
@ -64,7 +64,7 @@
|
||||
|
||||

|
||||
|
||||
本图中,对所有边进行松弛,真正有效的松弛,只有松弛 边(节点1->节点2) 和 边(节点1->节点5) 。
|
||||
本图中,对所有边进行松弛,真正有效的松弛,只有松弛 边(节点1->节点2) 和 边(节点1->节点3) 。
|
||||
|
||||
而松弛 边(节点4->节点6) ,边(节点5->节点3)等等 都是无效的操作,因为 节点4 和 节点 5 都是没有被计算过的节点。
|
||||
|
||||
|
127
problems/kamacoder/0151.手机流畅运行的秘密.md
Normal file
127
problems/kamacoder/0151.手机流畅运行的秘密.md
Normal file
@ -0,0 +1,127 @@
|
||||
# 151. 手机流畅运行的秘密
|
||||
|
||||
[题目链接](https://kamacoder.com/problempage.php?pid=1229)
|
||||
|
||||
先运行 能留下电量多的 任务,才能有余电运行其他任务。
|
||||
|
||||
任务1,1:10 ,运行完 能留下 9个电
|
||||
|
||||
任务2,2:12,运行完 能留下 10个电
|
||||
|
||||
任务3,3:10,运行完 能留下 7个电。
|
||||
|
||||
运行顺序: 任务2 -> 任务1 -> 任务3
|
||||
|
||||
按照 最低初始电量 - 耗电量,从大到小排序。
|
||||
|
||||
计算总电量,需要 从小到大 遍历, 不断取 总电量 + 任务耗电量 与 任务最低初始电量 的最大值。
|
||||
|
||||
```CPP
|
||||
#include<bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
bool cmp(const pair<int,int>& taskA, const pair<int,int>& taskB) {
|
||||
return (taskA.second - taskA.first) < (taskB.second - taskB.first);
|
||||
}
|
||||
int main() {
|
||||
string str, tmp;
|
||||
vector<pair<int,int>> tasks;
|
||||
|
||||
//处理输入
|
||||
getline(cin, str);
|
||||
stringstream ss(str);
|
||||
while (getline(ss, tmp, ',')) {
|
||||
int p = tmp.find(":");
|
||||
string a = tmp.substr(0, p);
|
||||
string b = tmp.substr(p + 1);
|
||||
tasks.push_back({stoi(a), stoi(b)});
|
||||
}
|
||||
|
||||
// 按照差值从小到大排序
|
||||
sort(tasks.begin(), tasks.end(), cmp);
|
||||
|
||||
// 收集结果
|
||||
int result = 0;
|
||||
for (int i = 0 ; i < tasks.size(); i++) {
|
||||
result = max(result + tasks[i].first, tasks[i].second);
|
||||
}
|
||||
|
||||
result = result <= 4800 ? result : -1;
|
||||
cout << result << endl;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Java版本:
|
||||
|
||||
```Java
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
Scanner sc = new Scanner(System.in);
|
||||
String str = sc.nextLine();
|
||||
String[] tasksArray = str.split(",");
|
||||
List<Pair> tasks = Arrays.stream(tasksArray)
|
||||
.map(task -> {
|
||||
String[] parts = task.split(":");
|
||||
return new Pair(Integer.parseInt(parts[0]), Integer.parseInt(parts[1]));
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 按照差值从小到大排序
|
||||
Collections.sort(tasks, (taskA, taskB) ->
|
||||
(taskA.second - taskA.first) - (taskB.second - taskB.first)
|
||||
);
|
||||
|
||||
// 收集结果
|
||||
int result = 0;
|
||||
for (Pair task : tasks) {
|
||||
result = Math.max(result + task.first, task.second);
|
||||
}
|
||||
|
||||
result = result <= 4800 ? result : -1;
|
||||
System.out.println(result);
|
||||
}
|
||||
}
|
||||
|
||||
class Pair {
|
||||
int first;
|
||||
int second;
|
||||
|
||||
Pair(int first, int second) {
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Python版本:
|
||||
|
||||
```python
|
||||
def main():
|
||||
import sys
|
||||
input = sys.stdin.read
|
||||
|
||||
str = input().strip()
|
||||
tasks = []
|
||||
for tmp in str.split(','):
|
||||
a, b = map(int, tmp.split(':'))
|
||||
tasks.append((a, b))
|
||||
|
||||
# 按照差值从小到大排序
|
||||
tasks.sort(key=lambda task: task[1] - task[0])
|
||||
|
||||
# 收集结果
|
||||
result = 0
|
||||
for task in tasks:
|
||||
result = max(result + task[0], task[1])
|
||||
|
||||
result = result if result <= 4800 else -1
|
||||
print(result)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
```
|
121
problems/kamacoder/0152.小米手机通信校准.md
Normal file
121
problems/kamacoder/0152.小米手机通信校准.md
Normal file
@ -0,0 +1,121 @@
|
||||
|
||||
|
||||
# 152. 小米手机通信校准
|
||||
|
||||
[题目链接](https://kamacoder.com/problempage.php?pid=1230)
|
||||
|
||||
一道模拟题,但比较考察 代码能力。
|
||||
|
||||
遍历去找 里 freq 最近的 freg就好, 需要记录刚遍历过的的freg和 loss,因为可能有 相邻一样的 freg。
|
||||
|
||||
```CPP
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
int freq;
|
||||
cin >> freq;
|
||||
string data;
|
||||
double result = 0;
|
||||
int last_freg = 0; // 记录上一个 freg
|
||||
int last_loss = 0; // 记录上一个loss
|
||||
while(cin >> data) {
|
||||
int index = data.find(':');
|
||||
int freg = stoi(data.substr(0, index)); // 获取 freg 和 loss
|
||||
int loss = stoi(data.substr(index + 1));
|
||||
// 两遍一样
|
||||
if(abs(freg - freq) == abs(last_freg - freq)) {
|
||||
result = (double)(last_loss + loss)/2.0;
|
||||
} // 否则更新最新的result
|
||||
else if(abs(freg - freq) < abs(last_freg - freq)){
|
||||
result = (double)loss;
|
||||
}
|
||||
last_freg = freg;
|
||||
last_loss = loss;
|
||||
}
|
||||
printf("%.1lf\n", result);
|
||||
return 0;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Java 版本:
|
||||
|
||||
```Java
|
||||
|
||||
import java.util.Scanner;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
Scanner sc = new Scanner(System.in);
|
||||
int freq = sc.nextInt();
|
||||
sc.nextLine(); // 读取换行符
|
||||
|
||||
String inputLine = sc.nextLine(); // 读取包含所有后续输入的行
|
||||
String[] data = inputLine.split(" "); // 根据空格分割输入
|
||||
|
||||
double result = 0;
|
||||
int lastFreq = 0; // 记录上一个 freg
|
||||
int lastLoss = 0; // 记录上一个 loss
|
||||
|
||||
for (String entry : data) {
|
||||
int index = entry.indexOf(':');
|
||||
int freg = Integer.parseInt(entry.substring(0, index)); // 获取 freg 和 loss
|
||||
int loss = Integer.parseInt(entry.substring(index + 1));
|
||||
|
||||
// 两遍一样
|
||||
if (Math.abs(freg - freq) == Math.abs(lastFreq - freq)) {
|
||||
result = (double) (lastLoss + loss) / 2.0;
|
||||
}
|
||||
// 否则更新最新的 result
|
||||
else if (Math.abs(freg - freq) < Math.abs(lastFreq - freq)) {
|
||||
result = (double) loss;
|
||||
}
|
||||
|
||||
lastFreq = freg;
|
||||
lastLoss = loss;
|
||||
}
|
||||
|
||||
System.out.printf("%.1f\n", result);
|
||||
sc.close();
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Python版本:
|
||||
|
||||
```python
|
||||
def main():
|
||||
import sys
|
||||
input = sys.stdin.read
|
||||
data = input().split()
|
||||
|
||||
freq = int(data[0])
|
||||
result = 0
|
||||
last_freg = 0 # 记录上一个 freg
|
||||
last_loss = 0 # 记录上一个 loss
|
||||
|
||||
for i in range(1, len(data)):
|
||||
item = data[i]
|
||||
index = item.find(':')
|
||||
freg = int(item[:index]) # 获取 freg 和 loss
|
||||
loss = int(item[index + 1:])
|
||||
|
||||
# 两遍一样
|
||||
if abs(freg - freq) == abs(last_freg - freq):
|
||||
result = (last_loss + loss) / 2.0
|
||||
# 否则更新最新的 result
|
||||
elif abs(freg - freq) < abs(last_freg - freq):
|
||||
result = loss
|
||||
|
||||
last_freg = freg
|
||||
last_loss = loss
|
||||
|
||||
print(f"{result:.1f}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
||||
```
|
Reference in New Issue
Block a user