2024-01-03:用go语言,给你两个长度为 n 下标从 0 开始的整数数组 cost 和 time, 分别表示给 n 堵不同的墙刷油漆需要的开销和时间。你有两名油漆匠, 一位需要 付费 的油漆匠
2024-01-03:用go語言,給你兩個長度為 n 下標從 0 開始的整數數組 cost 和 time,
分別表示給 n 堵不同的墻刷油漆需要的開銷和時間。你有兩名油漆匠,
一位需要 付費 的油漆匠,刷第 i 堵墻需要花費 time[i] 單位的時間,
開銷為 cost[i] 單位的錢。
一位 免費 的油漆匠,刷 任意 一堵墻的時間為 1 單位,開銷為 0,
但是必須在付費油漆匠 工作 時,免費油漆匠才會工作。
請你返回刷完 n 堵墻最少開銷為多少?
輸入:cost = [1,2,3,2], time = [1,2,3,2]。
輸出:3。
來自力扣。2742. 給墻壁刷油漆。
答案2024-01-03:
來自左程云。
靈捷3.5
大體過程如下:
paintWalls1 函數
1.paintWalls1 函數是基于遞歸方法的解決方案。
2.在 process1 函數中,通過遞歸方式將每種情況下的最小開銷計算出來。
3.遞歸調用時考慮兩種情況,選擇當前墻刷或者不刷,計算出最小開銷。
4.該方法在遞歸調用的過程中可能會有很多重復計算,效率可能不高。
paintWalls2 函數
1.paintWalls2 函數采用了記憶化搜索的方式。
2.定義了一個二維數組 dp 用于記錄已經計算過的結果,避免重復計算。
3.通過遞歸+記憶化搜索的方式優化了重復計算,提高了效率。
paintWalls3 函數
1.paintWalls3 函數采用了動態規劃的方式。
2.使用一個一維數組 dp 保存不同墻數下的最小開銷。
3.結合循環和動態遞推的方式,迭代計算每墻的最小開銷,直到第 n 墻。
時間和空間復雜度
-
時間復雜度:
-
paintWalls1使用了遞歸,可能有大量重復計算,其時間復雜度為 O(2^n)。 -
paintWalls2和paintWalls3使用了記憶化搜索和動態規劃,時間復雜度都為 O(n^2),其中 n 為墻的數量。
-
-
空間復雜度:
-
paintWalls1和paintWalls2的額外空間復雜度為 O(n^2),因為它們都使用了二維數組存儲中間結果。 -
paintWalls3的額外空間復雜度為 O(n),因為它只用了一個一維數組保存中間結果。
-
go完整代碼如下:
package main
import (
"fmt"
"math"
)
// paintWalls1 represents the first function from the given Java code.
func paintWalls1(cost []int, time []int) int {
return process1(cost, time, 0, len(cost))
}
// process1 is the recursive function as mentioned in the Java code.
func process1(cost []int, time []int, i int, s int) int {
if s <= 0 {
return 0
}
// s > 0
if i == len(cost) {
return math.MaxInt32
} else {
p1 := process1(cost, time, i+1, s)
p2 := math.MaxInt32
next2 := process1(cost, time, i+1, s-1-time[i])
if next2 != math.MaxInt32 {
p2 = cost[i] + next2
}
return int(math.Min(float64(p1), float64(p2)))
}
}
// paintWalls2 is the second function from the given Java code.
func paintWalls2(cost []int, time []int) int {
n := len(cost)
dp := make([][]int, n+1)
for i := range dp {
dp[i] = make([]int, n+1)
for j := range dp[i] {
dp[i][j] = -1
}
}
return process2(cost, time, 0, n, dp)
}
// process2 represents the recursive function in the second approach of the Java code.
func process2(cost []int, time []int, i int, s int, dp [][]int) int {
if s <= 0 {
return 0
}
if dp[i][s] != -1 {
return dp[i][s]
}
var ans int
if i == len(cost) {
ans = math.MaxInt32
} else {
p1 := process2(cost, time, i+1, s, dp)
p2 := math.MaxInt32
next2 := process2(cost, time, i+1, s-1-time[i], dp)
if next2 != math.MaxInt32 {
p2 = cost[i] + next2
}
ans = int(math.Min(float64(p1), float64(p2)))
}
dp[i][s] = ans
return ans
}
// paintWalls3 is the third function from the given Java code.
func paintWalls3(cost []int, time []int) int {
n := len(cost)
dp := make([]int, n+1)
for i := range dp {
dp[i] = math.MaxInt32
}
dp[0] = 0
for i := n - 1; i >= 0; i-- {
for s := n; s >= 1; s-- {
if s-1-time[i] <= 0 {
dp[s] = int(math.Min(float64(dp[s]), float64(cost[i])))
} else if dp[s-1-time[i]] != math.MaxInt32 {
dp[s] = int(math.Min(float64(dp[s]), float64(cost[i]+dp[s-1-time[i]])))
}
}
}
return dp[n]
}
func main() {
cost := []int{1, 2, 3, 2}
time := []int{1, 2, 3, 2}
fmt.Println("Result 1:", paintWalls1(cost, time))
fmt.Println("Result 2:", paintWalls2(cost, time))
fmt.Println("Result 3:", paintWalls3(cost, time))
}
rust完整代碼如下:
fn paint_walls1(cost: Vec<i32>, time: Vec<i32>) -> i32 {
process1(&cost, &time, 0, cost.len() as i32)
}
fn process1(cost: &Vec<i32>, time: &Vec<i32>, i: i32, s: i32) -> i32 {
if s <= 0 {
return 0;
}
if (i as usize) == cost.len() {
return i32::MAX;
} else {
let p1 = process1(cost, time, i + 1, s);
let mut p2 = i32::MAX;
let next2 = process1(cost, time, i + 1, s - 1 - time[i as usize]);
if next2 != i32::MAX {
p2 = cost[i as usize] + next2;
}
return p1.min(p2);
}
}
fn paint_walls2(cost: Vec<i32>, time: Vec<i32>) -> i32 {
let n = cost.len();
let mut dp = vec![vec![-1; n + 1]; n + 1];
process2(&cost, &time, 0, n as i32, &mut dp)
}
fn process2(cost: &Vec<i32>, time: &Vec<i32>, i: i32, s: i32, dp: &mut Vec<Vec<i32>>) -> i32 {
if s <= 0 {
return 0;
}
if dp[i as usize][s as usize] != -1 {
return dp[i as usize][s as usize];
}
let ans;
if (i as usize) == cost.len() {
ans = i32::MAX;
} else {
let p1 = process2(cost, time, i + 1, s, dp);
let mut p2 = i32::MAX;
let next2 = process2(cost, time, i + 1, s - 1 - time[i as usize], dp);
if next2 != i32::MAX {
p2 = cost[i as usize] + next2;
}
ans = p1.min(p2);
}
dp[i as usize][s as usize] = ans;
ans
}
fn paint_walls3(cost: Vec<i32>, time: Vec<i32>) -> i32 {
let n = cost.len();
let mut dp = vec![i32::MAX; n + 1];
dp[0] = 0;
for i in (0..n).rev() {
for s in (1..=n as i32).rev() {
if s - 1 - time[i] <= 0 {
dp[s as usize] = dp[s as usize].min(cost[i]);
} else if dp[(s - 1 - time[i]) as usize] != i32::MAX {
dp[s as usize] = dp[s as usize].min(cost[i] + dp[(s - 1 - time[i]) as usize]);
}
}
}
dp[n]
}
fn main() {
let cost = vec![1, 2, 3, 2];
let time = vec![1, 2, 3, 2];
let result1 = paint_walls1(cost.clone(), time.clone());
let result2 = paint_walls2(cost.clone(), time.clone());
let result3 = paint_walls3(cost.clone(), time.clone());
println!("Result for paint_walls1: {}", result1);
println!("Result for paint_walls2: {}", result2);
println!("Result for paint_walls3: {}", result3);
}
c++完整代碼如下:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 暴力遞歸
int process1(vector<int>& cost, vector<int>& time, int i, int s) {
if (s <= 0) {
return 0;
}
if (i == cost.size()) {
return INT_MAX;
}
else {
int p1 = process1(cost, time, i + 1, s);
int p2 = INT_MAX;
int next2 = process1(cost, time, i + 1, s - 1 - time[i]);
if (next2 != INT_MAX) {
p2 = cost[i] + next2;
}
return min(p1, p2);
}
}
int paintWalls1(vector<int>& cost, vector<int>& time) {
return process1(cost, time, 0, cost.size());
}
// 暴力遞歸改記憶化搜索
int process2(vector<int>& cost, vector<int>& time, int i, int s, vector<vector<int>>& dp) {
if (s <= 0) {
return 0;
}
if (dp[i][s] != -1) {
return dp[i][s];
}
int ans;
if (i == cost.size()) {
ans = INT_MAX;
}
else {
int p1 = process2(cost, time, i + 1, s, dp);
int p2 = INT_MAX;
int next2 = process2(cost, time, i + 1, s - 1 - time[i], dp);
if (next2 != INT_MAX) {
p2 = cost[i] + next2;
}
ans = min(p1, p2);
}
dp[i][s] = ans;
return ans;
}
int paintWalls2(vector<int>& cost, vector<int>& time) {
int n = cost.size();
vector<vector<int>> dp(n + 1, vector<int>(n + 1, -1));
return process2(cost, time, 0, n, dp);
}
// 嚴格位置依賴的動態規劃 + 空間壓縮
int paintWalls3(vector<int>& cost, vector<int>& time) {
int n = cost.size();
vector<int> dp(n + 1, INT_MAX);
dp[0] = 0;
for (int i = n - 1; i >= 0; i--) {
for (int s = n; s >= 1; s--) {
if (s - 1 - time[i] <= 0) {
dp[s] = min(dp[s], cost[i]);
}
else if (dp[s - 1 - time[i]] != INT_MAX) {
dp[s] = min(dp[s], cost[i] + dp[s - 1 - time[i]]);
}
}
}
return dp[n];
}
int main() {
vector<int> cost = { 1, 2, 3, 2 };
vector<int> time = { 1, 2, 3, 2 };
cout << "Result for paintWalls1: " << paintWalls1(cost, time) << endl;
cout << "Result for paintWalls2: " << paintWalls2(cost, time) << endl;
cout << "Result for paintWalls3: " << paintWalls3(cost, time) << endl;
return 0;
}
c語言完整代碼如下:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int process1(int* cost, int* time, int i, int s, int costSize);
int paintWalls1(int* cost, int costSize, int* time, int timeSize) {
return process1(cost, time, 0, costSize, costSize);
}
int process1(int* cost, int* time, int i, int s, int costSize) {
if (s <= 0) {
return 0;
}
if (i == costSize) {
return INT_MAX;
}
else {
int p1 = process1(cost, time, i + 1, s, costSize);
int p2 = INT_MAX;
int next2 = process1(cost, time, i + 1, s - 1 - time[i], costSize);
if (next2 != INT_MAX) {
p2 = cost[i] + next2;
}
return (p1 < p2) ? p1 : p2;
}
}
int process2(int* cost, int* time, int i, int s, int costSize, int** dp);
int paintWalls2(int* cost, int costSize, int* time, int timeSize) {
int** dp = (int**)malloc((costSize + 1) * sizeof(int*));
for (int i = 0; i <= costSize; i++) {
dp[i] = (int*)malloc((costSize + 1) * sizeof(int));
for (int j = 0; j <= costSize; j++) {
dp[i][j] = -1;
}
}
int result = process2(cost, time, 0, costSize, costSize, dp);
for (int i = 0; i <= costSize; i++) {
free(dp[i]);
}
free(dp);
return result;
}
int process2(int* cost, int* time, int i, int s, int costSize, int** dp) {
if (s <= 0) {
return 0;
}
if (dp[i][s] != -1) {
return dp[i][s];
}
int ans;
if (i == costSize) {
ans = INT_MAX;
}
else {
int p1 = process2(cost, time, i + 1, s, costSize, dp);
int p2 = INT_MAX;
int next2 = process2(cost, time, i + 1, s - 1 - time[i], costSize, dp);
if (next2 != INT_MAX) {
p2 = cost[i] + next2;
}
ans = (p1 < p2) ? p1 : p2;
}
dp[i][s] = ans;
return ans;
}
int paintWalls3(int* cost, int costSize, int* time, int timeSize);
int paintWalls3(int* cost, int costSize, int* time, int timeSize) {
int* dp = (int*)malloc((costSize + 1) * sizeof(int));
for (int i = 0; i <= costSize; i++) {
dp[i] = INT_MAX;
}
dp[0] = 0;
for (int i = costSize - 1; i >= 0; i--) {
for (int s = costSize; s >= 1; s--) {
if (s - 1 - time[i] <= 0) {
dp[s] = (dp[s] < cost[i]) ? dp[s] : cost[i];
}
else if (dp[s - 1 - time[i]] != INT_MAX) {
dp[s] = (dp[s] < cost[i] + dp[s - 1 - time[i]]) ? dp[s] : cost[i] + dp[s - 1 - time[i]];
}
}
}
int result = dp[costSize];
free(dp);
return result;
}
int main() {
int cost[] = { 1, 2, 3, 2 };
int time[] = { 1, 2, 3, 2 };
int result1 = paintWalls1(cost, 4, time, 4);
printf("Result of paintWalls1: %d\n", result1);
int result2 = paintWalls2(cost, 4, time, 4);
printf("Result of paintWalls2: %d\n", result2);
int result3 = paintWalls3(cost, 4, time, 4);
printf("Result of paintWalls3: %d\n", result3);
return 0;
}
總結
以上是生活随笔為你收集整理的2024-01-03:用go语言,给你两个长度为 n 下标从 0 开始的整数数组 cost 和 time, 分别表示给 n 堵不同的墙刷油漆需要的开销和时间。你有两名油漆匠, 一位需要 付费 的油漆匠的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 蔚来 1600 座换电站达成:全国累计建
- 下一篇: 现实版铁甲钢拳!山东 3 人团队打造史上