華為OD機試真題——硬件產品銷售方案(2025A卷:100分)Java/python/JavaScript/C++/C語言/GO六種最佳實現

在這里插入圖片描述

2025 A卷 100分 題型

本文涵蓋詳細的問題分析、解題思路、代碼實現、代碼詳解、測試用例以及綜合分析;
并提供Java、python、JavaScript、C++、C語言、GO六種語言的最佳實現方式!

2025華為OD真題目錄+全流程解析/備考攻略/經驗分享

華為OD機試真題《硬件產品銷售方案》:


目錄

    • 題目名稱:硬件產品銷售方案
      • 題目描述
    • Java
      • 問題分析
      • 解題思路
      • 代碼實現
      • 代碼詳細解析
      • 示例測試
        • 示例1輸入:
        • 示例2輸入:
      • 綜合分析
    • python
      • 問題分析
      • 解題思路
      • 代碼實現
      • 代碼詳細解析
      • 示例測試
        • 示例1輸入:
        • 示例2輸入:
      • 綜合分析
    • JavaScript
      • 問題分析
      • 解題思路
      • 代碼實現
      • 代碼詳細解析
      • 示例測試
        • 示例1輸入:
        • 示例2輸入:
      • 綜合分析
    • C++
      • 問題分析
      • 解題思路
      • 代碼實現
      • 代碼詳細解析
      • 示例測試
        • 示例1輸入:
        • 示例2輸入:
      • 綜合分析
    • C語言
      • 問題分析
      • 解題思路
      • 代碼實現
      • 代碼詳細解析
      • 示例測試
        • 示例1輸入:
        • 示例2輸入:
      • 綜合分析
    • GO
      • 問題分析
      • 解題思路
      • 代碼實現
      • 代碼詳細解析
        • 1. 輸入處理
        • 2. 回溯函數
        • 3. 結果格式化
      • 示例測試
        • 示例1輸入:
        • 示例2輸入:
      • 綜合分析
      • 擴展
    • 更多內容:


題目名稱:硬件產品銷售方案


維度描述
知識點回溯算法(DFS)、剪枝優化、排序預處理
時間限制1秒
空間限制256MB
限定語言不限

題目描述

某公司推出多種硬件產品,每種產品包含若干型號且價格唯一。現需為合作廠商列出所有總金額等于 amount 元的產品組合。已知產品庫存充足,且價格列表 price 中的元素互不相同。

輸入描述

  • 第一行為正整數 amount,表示采購金額。
  • 第二行為逗號分隔的正整數列表 price,表示各型號的價格。

輸出描述

  • 輸出所有可能的組合列表,格式為二維數組。若無法組合,返回空列表。
  • 注意:組合中元素的順序不同視為不同方案(如 [100, 200][200, 100] 視為兩種組合),但實際題目中因允許重復選擇同一產品,需按順序枚舉。

示例1
輸入:

500  
100,200,300,500  

輸出:

[[100,100,100,100,100], [100,100,100,200], [100,100,300], [100,200,200], [200,300], [500]]  

示例2
輸入:

100  
100  

輸出:

  

Java

問題分析

我們需要找到所有可能的價格組合,使得它們的總和等于給定的金額。每個價格可以重復使用,且組合中的元素順序不同視為不同方案。為避免重復組合,需按非降序排列生成組合。

解題思路

  1. 排序預處理:將價格數組排序,確保組合按非降序生成。
  2. 回溯算法(DFS):遞歸遍歷所有可能的組合,記錄滿足條件的組合。
  3. 剪枝優化:當當前路徑的和超過目標金額時,停止進一步搜索。

代碼實現

import java.util.*;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int amount = Integer.parseInt(sc.nextLine());String[] prices = sc.nextLine().split(",");List<Integer> priceList = new ArrayList<>();for (String p : prices) {priceList.add(Integer.parseInt(p.trim()));}// 排序以便后續剪枝和去重Collections.sort(priceList);List<List<Integer>> result = new ArrayList<>();backtrack(priceList, amount, 0, new ArrayList<>(), 0, result);// 輸出格式化System.out.println(formatResult(result));}/*** 回溯函數,遞歸生成所有可能的組合* @param prices   排序后的價格列表* @param target   目標金額* @param start    當前遍歷的起始索引(避免重復組合)* @param path     當前路徑(組合)* @param sum      當前路徑的和* @param result   結果集*/private static void backtrack(List<Integer> prices, int target, int start, List<Integer> path, int sum, List<List<Integer>> result) {if (sum > target) return;      // 剪枝:總和超過目標,停止遞歸if (sum == target) {          // 找到有效組合,加入結果集result.add(new ArrayList<>(path));return;}// 從start開始遍歷,避免生成重復組合for (int i = start; i < prices.size(); i++) {int price = prices.get(i);if (sum + price > target) break; // 剪枝:后續元素更大,無需繼續path.add(price);                  // 將當前元素加入路徑backtrack(prices, target, i, path, sum + price, result);path.remove(path.size() - 1);     // 回溯:移除當前元素}}/*** 將結果列表格式化為題目要求的字符串形式*/private static String formatResult(List<List<Integer>> result) {if (result.isEmpty()) return "[]";StringBuilder sb = new StringBuilder();sb.append("[");for (int i = 0; i < result.size(); i++) {sb.append("[");List<Integer> list = result.get(i);for (int j = 0; j < list.size(); j++) {sb.append(list.get(j));if (j < list.size() - 1) sb.append(",");}sb.append("]");if (i < result.size() - 1) sb.append(", ");}sb.append("]");return sb.toString();}
}

代碼詳細解析

  1. 輸入處理:讀取金額和價格列表,將價格轉換為整數并排序。
  2. 回溯函數
    • 終止條件:若當前和超過目標,直接返回;若等于目標,保存組合。
    • 循環遍歷:從start索引開始遍歷,避免重復組合。
    • 剪枝優化:若當前和加當前價格超過目標,終止后續循環。
  3. 路徑管理:遞歸前添加當前價格到路徑,遞歸后移除(回溯)。
  4. 結果格式化:將結果列表轉換為符合題目要求的字符串格式。

示例測試

示例1輸入:
500  
100,200,300,500  

輸出

[[100,100,100,100,100], [100,100,100,200], [100,100,300], [100,200,200], [200,300], [500]]

解析

  • 排序后價格為[100,200,300,500]
  • 通過回溯生成所有非降序組合,如[100×5][100×3+200]等。
示例2輸入:
100  
100  

輸出


解析

  • 唯一可能的組合是[100]

綜合分析

  1. 時間復雜度:最壞情況下為O(2^n),但通過排序和剪枝優化,實際效率較高。
  2. 空間復雜度:O(n)遞歸棧深度,結果存儲空間為O(k·m)(k為組合數,m為平均組合長度)。
  3. 優勢
    • 剪枝優化:通過排序和提前終止無效搜索,減少計算量。
    • 去重機制:通過固定遍歷起點,避免生成重復組合。
  4. 適用場景:適用于小規模數據(價格列表長度≤30),符合題目約束。

python

問題分析

我們需要找到所有可能的價格組合,使得它們的總和等于給定的金額。每個價格可以重復使用,且組合按非降序排列以避免重復。

解題思路

  1. 排序預處理:將價格數組排序,確保組合按非降序生成。
  2. 回溯算法(DFS):遞歸遍歷所有可能的組合,記錄滿足條件的組合。
  3. 剪枝優化:當當前路徑的和超過目標金額時,停止進一步搜索。

代碼實現

def main():amount = int(input())prices = list(map(int, input().strip().split(',')))prices.sort()result = []def backtrack(start, path, current_sum):if current_sum == amount:result.append(path.copy())returnfor i in range(start, len(prices)):price = prices[i]if current_sum + price > amount:break  # 剪枝:后續價格更大,無需繼續path.append(price)backtrack(i, path, current_sum + price)path.pop()backtrack(0, [], 0)print(format_result(result))def format_result(result):if not result:return "[]"formatted = []for combo in result:formatted.append("[{}]".format(",".join(map(str, combo))))return "[{}]".format(", ".join(formatted))if __name__ == "__main__":main()

代碼詳細解析

  1. 輸入處理:讀取金額和價格列表,轉換為整數并排序。
  2. 回溯函數
    • 終止條件:若當前和等于目標金額,保存組合。
    • 循環遍歷:從start索引開始,保證組合非降序。
    • 剪枝優化:若當前和加當前價格超過目標,終止循環。
  3. 路徑管理:遞歸前添加價格到路徑,遞歸后移除(回溯)。
  4. 結果格式化:將結果轉換為題目要求的二維數組格式。

示例測試

示例1輸入:
500
100,200,300,500

輸出

[[100,100,100,100,100],[100,100,100,200],[100,100,300],[100,200,200],[200,300],[500]]

解析

  • 排序后價格為[100,200,300,500]
  • 通過回溯生成所有非降序組合,如[100×5][100×3+200]等。
示例2輸入:
100
100

輸出


解析

  • 唯一可能的組合是[100]

綜合分析

  1. 時間復雜度:最壞情況下為O(2?),但通過剪枝優化,實際效率較高。
  2. 空間復雜度:O(n)遞歸棧深度,結果存儲為O(k·m)(k為組合數,m為平均組合長度)。
  3. 優勢
    • 剪枝優化:通過排序提前終止無效搜索。
    • 去重機制:固定遍歷起點,保證組合非降序。
  4. 適用場景:適用于小規模數據(價格列表長度≤30)。

JavaScript

問題分析

我們需要找到所有可能的價格組合,使得它們的總和等于給定的金額。每個價格可以重復使用,組合需按非降序排列以避免重復。


解題思路

  1. 排序預處理:將價格數組排序,確保組合按非降序生成。
  2. 回溯算法(DFS):遞歸遍歷所有可能的組合,記錄滿足條件的組合。
  3. 剪枝優化:當當前路徑的和超過目標金額時,停止進一步搜索。

代碼實現

const readline = require('readline');const rl = readline.createInterface({input: process.stdin,output: process.stdout,terminal: false
});let lines = [];
rl.on('line', (line) => {lines.push(line.trim());
}).on('close', () => {const amount = parseInt(lines[0]);const prices = lines[1].split(',').map(Number).sort((a, b) => a - b);const result = [];// 回溯函數定義const backtrack = (start, path, currentSum) => {if (currentSum === amount) {result.push([...path]); // 存儲路徑副本return;}for (let i = start; i < prices.length; i++) {const price = prices[i];if (currentSum + price > amount) break; // 剪枝:超過目標金額path.push(price);                       // 添加當前價格backtrack(i, path, currentSum + price); // 遞歸探索path.pop();                             // 回溯:移除最后添加的價格}};backtrack(0, [], 0);  // 初始調用console.log(formatResult(result)); // 格式化輸出
});// 結果格式化函數
const formatResult = (result) => {if (result.length === 0) return '[]';const formatted = result.map(combo => `[${combo.join(',')}]`);return `[${formatted.join(', ')}]`;
};

代碼詳細解析

  1. 輸入處理

    • 使用 readline 模塊讀取兩行輸入,分別存儲金額和價格列表。
    • 將價格轉換為數字數組并排序,確保后續生成非降序組合。
  2. 回溯函數

    • 參數說明
      • start:當前遍歷的起始索引,避免重復組合。
      • path:當前路徑(組合)。
      • currentSum:當前路徑的價格總和。
    • 終止條件:當 currentSum === amount 時,將路徑副本存入結果。
    • 循環遍歷:從 start 開始,避免生成逆序組合。
    • 剪枝優化:若當前價格導致總和超限,終止后續循環。
    • 路徑管理:遞歸前添加價格,遞歸后彈出(回溯)。
  3. 結果格式化

    • 處理空結果返回 []
    • 將每個組合轉換為字符串格式,用逗號分隔元素。

示例測試

示例1輸入:
500  
100,200,300,500  

輸出

[[100,100,100,100,100], [100,100,100,200], [100,100,300], [100,200,200], [200,300], [500]]

解析

  • 排序后價格為 [100,200,300,500]
  • 回溯生成所有非降序組合,如 [100×5][100×3+200] 等。
示例2輸入:
100  
100  

輸出


解析

  • 唯一可能的組合是 [100],直接命中目標金額。

綜合分析

  1. 時間復雜度:O(2?)

    • 最壞情況下需遍歷所有組合,但通過剪枝大幅減少實際計算量。
    • 示例1中有效剪枝:當 100×5=500 后,跳過更大價格的無效路徑。
  2. 空間復雜度:O(n2)

    • 遞歸調用棧深度為 O(n),結果存儲空間為 O(k·m),k為組合數,m為平均組合長度。
  3. 優勢

    • 去重機制:通過固定遍歷起點,保證組合非降序。
    • 剪枝優化:提前終止無效路徑,提升效率。
  4. 適用場景

    • 價格列表長度 ≤ 30 的中小規模數據。
    • 需要精確枚舉所有可能性的場景,如商品組合推薦。

C++

問題分析

我們需要找到所有可能的價格組合,使得它們的總和等于給定的金額。每個價格可以重復使用,組合需按非降序排列以避免重復。


解題思路

  1. 排序預處理:將價格數組排序,確保組合按非降序生成。
  2. 回溯算法(DFS):遞歸遍歷所有可能的組合,記錄滿足條件的組合。
  3. 剪枝優化:當當前路徑的和超過目標金額時,停止進一步搜索。

代碼實現

#include <iostream>
#include <vector>
#include <sstream>
#include <algorithm>using namespace std;void backtrack(const vector<int>& prices, int target, int start, vector<int>& path, int sum, vector<vector<int>>& result) {if (sum == target) {result.push_back(path);return;}for (int i = start; i < prices.size(); ++i) {if (sum + prices[i] > target) break;  // 剪枝:后續價格更大,無需繼續path.push_back(prices[i]);             // 添加當前價格backtrack(prices, target, i, path, sum + prices[i], result);path.pop_back();                      // 回溯:移除最后添加的價格}
}string formatResult(const vector<vector<int>>& result) {if (result.empty()) return "[]";stringstream ss;ss << "[";for (size_t i = 0; i < result.size(); ++i) {ss << "[";const auto& combo = result[i];for (size_t j = 0; j < combo.size(); ++j) {ss << combo[j];if (j != combo.size() - 1) ss << ",";}ss << "]";if (i != result.size() - 1) ss << ", ";}ss << "]";return ss.str();
}int main() {int amount;cin >> amount;cin.ignore();  // 忽略換行符string line;getline(cin, line);vector<int> prices;stringstream ss(line);string token;while (getline(ss, token, ',')) {prices.push_back(stoi(token));}sort(prices.begin(), prices.end());  // 排序以便剪枝和去重vector<vector<int>> result;vector<int> path;backtrack(prices, amount, 0, path, 0, result);cout << formatResult(result) << endl;return 0;
}

代碼詳細解析

  1. 輸入處理

    • cin >> amount 讀取金額。
    • getline(cin, line) 讀取價格行,并用 stringstream 分割為整數數組。
    • sort() 對價格排序,確保后續生成非降序組合。
  2. 回溯函數

    • 參數說明
      • prices:排序后的價格數組。
      • target:目標金額。
      • start:當前遍歷的起始索引,避免生成逆序組合。
      • path:當前路徑(組合)。
      • sum:當前路徑的和。
      • result:結果集。
    • 終止條件:當 sum == target 時,將路徑存入結果。
    • 剪枝優化:若當前價格導致總和超限,終止循環(break)。
    • 路徑管理:遞歸前 push_back,遞歸后 pop_back 恢復狀態。
  3. 結果格式化

    • 處理空結果返回 []
    • 使用嵌套循環將每個組合轉換為字符串,符合題目要求的二維數組格式。

示例測試

示例1輸入:
500
100,200,300,500

輸出

[[100,100,100,100,100],[100,100,100,200],[100,100,300],[100,200,200],[200,300],[500]]

解析

  • 排序后價格為 [100,200,300,500]
  • 回溯生成所有非降序組合,如 [100×5][100×3+200] 等。
示例2輸入:
100
100

輸出


解析

  • 唯一可能的組合是 [100],直接命中目標金額。

綜合分析

  1. 時間復雜度:O(2?)

    • 最壞情況下需遍歷所有組合,但通過剪枝大幅減少實際計算量。
    • 示例1中剪枝跳過所有無效路徑(如 100×6)。
  2. 空間復雜度:O(n2)

    • 遞歸棧深度為 O(n),結果存儲空間為 O(k·m),k為組合數,m為平均組合長度。
  3. 優勢

    • 去重機制:固定遍歷起點,保證組合非降序。
    • 剪枝優化:提前終止無效路徑,提升效率。
  4. 適用場景

    • 價格列表長度 ≤ 30 的中小規模數據。
    • 需要精確枚舉所有可能性的場景,如商品組合推薦。

C語言

問題分析

我們需要找到所有可能的價格組合,使得它們的總和等于給定的金額。每個價格可以重復使用,組合需按非降序排列以避免重復。


解題思路

  1. 排序預處理:將價格數組排序,確保組合按非降序生成。
  2. 回溯算法(DFS):遞歸遍歷所有可能的組合,記錄滿足條件的組合。
  3. 剪枝優化:當當前路徑的和超過目標金額時,停止進一步搜索。

代碼實現

#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 定義動態數組結構體(存儲結果集)
typedef struct {int **data;     // 二維數組存儲組合int *sizes;     // 每個組合的長度int capacity;   // 當前分配的容量int size;       // 實際元素數量
} ResultList;// 初始化結果集
ResultList* createResultList(int initialCapacity) {ResultList *list = malloc(sizeof(ResultList));list->data = malloc(initialCapacity * sizeof(int*));list->sizes = malloc(initialCapacity * sizeof(int));list->capacity = initialCapacity;list->size = 0;return list;
}// 向結果集中添加組合
void addToResult(ResultList *list, const int *path, int pathSize) {if (list->size >= list->capacity) {  // 擴容list->capacity *= 2;list->data = realloc(list->data, list->capacity * sizeof(int*));list->sizes = realloc(list->sizes, list->capacity * sizeof(int));}// 復制路徑數據int *newPath = malloc(pathSize * sizeof(int));memcpy(newPath, path, pathSize * sizeof(int));list->data[list->size] = newPath;list->sizes[list->size] = pathSize;list->size++;
}// 釋放結果集內存
void freeResultList(ResultList *list) {for (int i = 0; i < list->size; i++) {free(list->data[i]);}free(list->data);free(list->sizes);free(list);
}// 回溯函數
void backtrack(int *prices, int pricesSize, int target, int start, int *path, int pathSize, int currentSum, ResultList *result) {if (currentSum == target) {addToResult(result, path, pathSize);return;}for (int i = start; i < pricesSize; i++) {if (currentSum + prices[i] > target) break;  // 剪枝path[pathSize] = prices[i];                   // 添加當前價格backtrack(prices, pricesSize, target, i, path, pathSize + 1, currentSum + prices[i], result);}
}// 比較函數(用于排序)
int compare(const void *a, const void *b) {return (*(int*)a - *(int*)b);
}// 格式化輸出結果
void formatResult(ResultList *result) {if (result->size == 0) {printf("[]\n");return;}printf("[");for (int i = 0; i < result->size; i++) {printf("[");for (int j = 0; j < result->sizes[i]; j++) {printf("%d", result->data[i][j]);if (j != result->sizes[i] - 1) printf(",");}printf("]");if (i != result->size - 1) printf(", ");}printf("]\n");
}int main() {// 讀取輸入int amount;scanf("%d", &amount);getchar();  // 讀取換行符char line[1000];fgets(line, sizeof(line), stdin);line[strcspn(line, "\n")] = '\0';  // 去除換行符// 分割字符串為價格數組int prices[100];int pricesSize = 0;char *token = strtok(line, ",");while (token != NULL) {prices[pricesSize++] = atoi(token);token = strtok(NULL, ",");}// 排序價格數組qsort(prices, pricesSize, sizeof(int), compare);// 初始化結果集和路徑ResultList *result = createResultList(10);int *path = malloc(100 * sizeof(int));  // 路徑最大長度設為100backtrack(prices, pricesSize, amount, 0, path, 0, 0, result);formatResult(result);// 釋放內存free(path);freeResultList(result);return 0;
}

代碼詳細解析

  1. 動態數組結構體ResultList 用于存儲所有找到的組合,包含二維數組、各組合長度、容量和實際大小。
  2. 內存管理函數
    • createResultList:初始化結果集,預分配內存。
    • addToResult:動態擴容并復制路徑數據。
    • freeResultList:遞歸釋放所有內存。
  3. 回溯函數
    • 通過 path 數組記錄當前組合,pathSize 記錄當前組合長度。
    • 剪枝邏輯:若當前和超過目標,終止后續循環。
  4. 輸入處理
    • fgets 讀取價格行,分割為整數數組。
    • 使用 qsort 對價格排序。
  5. 格式化輸出:遍歷結果集,按題目要求拼接字符串。

示例測試

示例1輸入:
500  
100,200,300,500  

輸出

[[100,100,100,100,100],[100,100,100,200],[100,100,300],[100,200,200],[200,300],[500]]

解析

  • 排序后價格為 [100,200,300,500]
  • 回溯生成所有非降序組合,如 [100×5][100×3+200] 等。
示例2輸入:
100  
100  

輸出


解析

  • 唯一可能的組合是 [100],直接命中目標金額。

綜合分析

  1. 時間復雜度:O(2?)
    • 最壞情況需遍歷所有組合,剪枝大幅減少實際計算量。
  2. 空間復雜度:O(k·m)
    • 結果集存儲所有組合,k為組合數,m為平均組合長度。
  3. 優勢
    • 手動內存管理:精準控制內存分配,適合嵌入式場景。
    • 高效剪枝:通過排序和提前終止優化性能。
  4. 適用場景
    • 需要嚴格內存控制的系統。
    • 中小規模數據(價格數量≤100)。

GO

問題分析

我們需要找到所有可能的價格組合,使得它們的總和等于給定的金額。每個價格可以重復使用,組合需按非降序排列以避免重復。例如,給定金額 500 和價格列表 [100,200,300,500],組合 [100,100,300] 是有效的,而 [300,100,100] 被視為重復。


解題思路

  1. 排序預處理:將價格數組排序,確保后續生成的組合按非降序排列。
  2. 回溯算法(DFS):遞歸遍歷所有可能的組合,記錄滿足條件的組合。
  3. 剪枝優化:當當前路徑的和超過目標金額時,停止進一步搜索。
  4. 路徑管理:通過切片動態管理當前路徑,回溯時恢復狀態。

代碼實現

package mainimport ("bufio""fmt""os""sort""strconv""strings"
)func main() {// 讀取輸入scanner := bufio.NewScanner(os.Stdin)scanner.Scan()amount, _ := strconv.Atoi(scanner.Text())scanner.Scan()pricesStr := strings.Split(scanner.Text(), ",")// 轉換為整數并排序prices := make([]int, len(pricesStr))for i, s := range pricesStr {prices[i], _ = strconv.Atoi(strings.TrimSpace(s))}sort.Ints(prices)// 回溯搜索var result [][]intbacktrack(prices, amount, 0, []int{}, 0, &result)// 格式化輸出fmt.Println(formatResult(result))
}// 回溯函數
func backtrack(prices []int, target, start int, path []int, sum int, result *[][]int) {if sum == target {// 深拷貝當前路徑,避免后續修改影響結果newPath := make([]int, len(path))copy(newPath, path)*result = append(*result, newPath)return}for i := start; i < len(prices); i++ {price := prices[i]if sum+price > target {break // 剪枝:后續價格更大,無需繼續}// 添加當前價格到路徑path = append(path, price)backtrack(prices, target, i, path, sum+price, result)// 回溯:移除最后添加的價格path = path[:len(path)-1]}
}// 結果格式化函數
func formatResult(result [][]int) string {if len(result) == 0 {return "[]"}str := "["for i, combo := range result {str += "["for j, num := range combo {str += strconv.Itoa(num)if j < len(combo)-1 {str += ","}}str += "]"if i < len(result)-1 {str += ", "}}str += "]"return str
}

代碼詳細解析

1. 輸入處理
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
amount, _ := strconv.Atoi(scanner.Text())
  • 使用 bufio.Scanner 逐行讀取輸入。
  • 第一行轉換為整數金額 amount
pricesStr := strings.Split(scanner.Text(), ",")
prices := make([]int, len(pricesStr))
for i, s := range pricesStr {prices[i], _ = strconv.Atoi(strings.TrimSpace(s))
}
sort.Ints(prices)
  • 第二行分割為字符串數組,轉換為整數切片。
  • 對價格排序,確保后續生成非降序組合。
2. 回溯函數
func backtrack(prices []int, target, start int, path []int, sum int, result *[][]int) {if sum == target {newPath := make([]int, len(path))copy(newPath, path)*result = append(*result, newPath)return}// 循環邏輯...
}
  • 參數說明
    • prices:排序后的價格列表。
    • target:目標金額。
    • start:當前搜索的起始索引(避免重復組合)。
    • path:當前路徑(組合)。
    • sum:當前路徑的總和。
    • result:存儲結果的切片指針。
for i := start; i < len(prices); i++ {price := prices[i]if sum+price > target {break // 剪枝}path = append(path, price)backtrack(prices, target, i, path, sum+price, result)path = path[:len(path)-1] // 回溯
}
  • 剪枝邏輯:若當前價格導致總和超限,終止后續循環。
  • 路徑管理:遞歸前添加價格到路徑,遞歸后移除(回溯)。
3. 結果格式化
func formatResult(result [][]int) string {// 拼接字符串邏輯...
}
  • 處理空結果返回 []
  • 使用嵌套循環將每個組合轉換為目標格式的字符串。

示例測試

示例1輸入:
500  
100,200,300,500  

輸出

[[100,100,100,100,100],[100,100,100,200],[100,100,300],[100,200,200],[200,300],[500]]

解析

  1. 排序后價格為 [100,200,300,500]
  2. 遞歸過程:
    • 選擇 100 5次 → [100×5]
    • 選擇 100 3次后選 200[100×3,200]
    • 其他組合類似,最終輸出所有非降序組合。
示例2輸入:
100  
100  

輸出


解析

  • 唯一可能的組合是 [100],直接命中目標金額。

綜合分析

  1. 時間復雜度

    • 最壞情況:O(2?),其中 n 為價格列表長度。
    • 剪枝優化后:實際運行時間遠小于理論值,例如示例1中跳過所有 price > 500 的路徑。
  2. 空間復雜度

    • 遞歸棧:O(n),取決于價格列表長度。
    • 結果存儲:O(k·m),k 為組合數,m 為平均組合長度。
  3. 優勢

    • 避免重復組合:通過排序和固定起始索引 start 實現。
    • 內存高效:Go 的切片動態擴容機制減少內存浪費。
  4. 適用場景

    • 價格數量 ≤ 100 的中小規模數據。
    • 需要精確枚舉所有可能性的場景(如商品推薦系統)。

擴展

Go語言特性帶來的優勢:

  1. 切片動態管理:無需手動處理數組擴容,簡化代碼。
  2. 值傳遞與指針:通過指針傳遞結果切片,避免深拷貝開銷。
  3. 內置排序函數sort.Ints 一行代碼完成排序。

潛在改進方向:

  1. 并行計算:利用 goroutine 分割搜索空間,加速大規模數據處理。
  2. 內存池優化:預分配結果切片內存,減少動態擴容次數。
  3. 字典樹剪枝:對價格列表構建前綴樹,進一步優化剪枝邏輯。

更多內容:

https://www.kdocs.cn/l/cvk0eoGYucWA

本文發表于【紀元A夢】,關注我,獲取更多實用教程/資源!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/76207.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/76207.shtml
英文地址,請注明出處:http://en.pswp.cn/web/76207.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【數據結構_6】雙向鏈表的實現

一、實現MyDLinkedList&#xff08;雙向鏈表&#xff09; package LinkedList;public class MyDLinkedList {//首先我們要創建節點&#xff08;因為雙向鏈表和單向鏈表的節點不一樣&#xff01;&#xff01;&#xff09;static class Node{public String val;public Node prev…

做Data+AI的長期主義者,加速全球化戰略布局

在Data與AI深度融合的新紀元&#xff0c;唯有秉持長期主義方能真正釋放數智化的深層價值。2025年是人工智能從技術爆發轉向規模化落地的關鍵節點&#xff0c;也是標志著袋鼠云即將迎來十周年的重要里程碑。2025年4月16日&#xff0c;袋鼠云成功舉辦了“做DataAI的長期主義者——…

構建基于PHP和MySQL的解夢系統:設計與實現

引言 夢境解析一直是人類心理學和文化研究的重要領域。隨著互聯網技術的發展,構建一個在線的解夢系統能夠幫助更多人理解自己夢境的含義。本文將詳細介紹如何使用PHP和MySQL構建一個功能完整的解夢系統,包括系統架構設計、數據庫模型、核心功能實現以及優化策略。 本文源碼下…

【桌面】【系統應用】Samba共享文件夾

目錄 場景一&#xff1a;銀河麒麟桌面與銀河麒麟桌面之間共享文件夾 環境準備 實現目標 操作步驟 &#xff08;一&#xff09;配置主機A共享文件夾 1、環境準備 2、在主機A創建共享文件夾 3、設置共享文件密碼 &#xff08;二&#xff09;主機B訪問主機A 場景二&…

OpenCV 圖形API(37)圖像濾波-----分離過濾器函數sepFilter()

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 應用一個可分離的線性濾波器到一個矩陣&#xff08;圖像&#xff09;。 該函數對矩陣應用一個可分離的線性濾波器。也就是說&#xff0c;首先&a…

webpack理解與使用

一、背景 webpack的最初目標是實現前端工程的模塊化&#xff0c;旨在更高效的管理和維護項目中的每一個資源。 最早的時候&#xff0c;我們通過文件劃分的方式實現模塊化&#xff0c;也就是將每個功能及其相關狀態數據都放在一個JS文件中&#xff0c;約定每個文件就是一個獨立…

rac環境下,增加一個控制文件controlfile

先關閉節點二&#xff0c;在節點一上操作 1、查看控制文件個數和路徑 SQL> show parameter control 2、備份參數文件 SQL> create pfile/home/oracle/orcl.pfile20250417 from spfile; 3、修改控制文件參數 SQL> alter system set contr…

git安裝(windows)

通過網盤分享的文件&#xff1a;資料(1) 鏈接: https://pan.baidu.com/s/1MAenYzcQ436MlKbIYQidoQ 提取碼: evu6 點擊next 可修改安裝路徑 默認就行 一般從命令行調用&#xff0c;所以不用創建。 用vscode&#xff0c;所以這么選擇。

Spring Boot整合難點?AI一鍵生成全流程解決方案

在當今的軟件開發領域&#xff0c;Spring Boot 憑借其簡化開發流程、快速搭建項目的優勢&#xff0c;成為了眾多開發者的首選框架。然而&#xff0c;Spring Boot 的整合過程并非一帆風順&#xff0c;常常會遇到各種難點。而飛算 JavaAI 的出現&#xff0c;為解決這些問題提供了…

Python批量處理PDF圖片詳解(插入、壓縮、提取、替換、分頁、旋轉、刪除)

目錄 一、概述 二、 使用工具 三、Python 在 PDF 中插入圖片 3.1 插入圖片到現有PDF 3.2 插入圖片到新建PDF 3.3 批量插入多張圖片到PDF 四、Python 提取 PDF 圖片及其元數據 五、Python 替換 PDF 圖片 5.1 使用圖片替換圖片 5.2 使用文字替換圖片 六、Python 實現 …

山東大學軟件學院創新項目實訓開發日志(15)之中醫知識問答歷史對話查看bug處理后端信息響應成功但前端未獲取到

在開發中醫知識問答歷史對話查看功能的時候&#xff0c;出現了前后端信息獲取異同的問題&#xff0c;在經過非常非常非常艱難的查詢之后終于解決了這一問題&#xff0c;而這一問題的罪魁禍首就是后端沒有setter和getter方法&#xff01;&#xff01;&#xff01;&#xff01;&a…

Arkts應用全局UI狀態存儲和持久化V2(AppStorageV2、PersistenceV2和@Type)

目錄 應用全局UI狀態存儲和持久化V2版本 AppStorageV2 connect remove keys 示例 使用限制 PersistenceV2 connect remove keys save notifyOnError 示例 使用限制 Type 使用限制 應用全局UI狀態存儲和持久化V2版本 以下實例AppStorageV2、PersistenceV2和裝飾…

最大子序和問題——動態規劃/貪心算法解決

目錄 一&#xff1a;問題描述 二&#xff1a;解決思路1——動態規劃思想 三&#xff1a;C 語言代碼實現 四&#xff1a;復雜度分析 五&#xff1a;解決思路2——貪心算法思想 六&#xff1a;具體步驟 七: C語言代碼實現 八&#xff1a;復雜度分析 一&#xff1a;問題描述 …

【Python入門】文件讀取全攻略:5種常用格式(csv/excel/word/ppt/pdf)一鍵搞定 | 附完整代碼示例

大家好&#xff0c;我是唐叔&#xff01;今天給大家帶來一篇Python文件讀取的終極指南。無論是數據分析、辦公自動化還是爬蟲開發&#xff0c;文件讀取都是Python程序員必須掌握的核心技能。本文將詳細介紹Python處理5大常用文件格式的方法&#xff0c;包含完整可運行的代碼示例…

四、小白如何用Pygame制作一款跑酷類游戲(頁面暫停和主角跑步動作的實現)

四、小白如何用Pygame制作一款跑酷類游戲&#xff08;頁面暫停和主角跑步動作的實現&#xff09; 提示&#xff1a;寫完文章后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 四、小白如何用Pygame制作一款跑酷類游戲&#xff08;頁面暫停和主…

《基于 RNN 的股票預測模型代碼優化:從重塑到直接可視化》

在深度學習領域&#xff0c;使用循環神經網絡&#xff08;RNN&#xff09;進行股票價格預測是一個常見且具有挑戰性的任務。本文將圍繞一段基于 RNN 的股票預測代碼的改動前后差別展開&#xff0c;深入剖析代碼的優化思路和效果。 原始代碼思路與問題 原始代碼實現了一個完整…

Lambda 函數與 peek 操作的使用案例

Lambda 函數和 peek 操作是 Java 8 Stream API 中非常有用的特性&#xff0c;下面我將介紹它們的使用案例。 Lambda 函數使用案例 Lambda 表達式是 Java 8 引入的一種簡潔的匿名函數表示方式。 集合操作 List<String> names Arrays.asList("Alice", "B…

Docker私有倉庫頁面訪問實現

通過 docker run -d -p 5000:5000 --name registry registry:2 命令搭建的Docker私有倉庫默認不提供網頁訪問界面。它是一個基于API的后端服務&#xff0c;主要用于鏡像的存儲和管理。但可以通過以下兩種方式實現網頁訪問&#xff1a; 一、通過第三方Web UI工具擴展 1. 使用 D…

[王陽明代數講義]語言模型核心代碼調研

語言模型核心代碼調研 基于Consciciteation?的才氣張量持續思考綜述將文本生成建模為才氣張量網絡擴散過程&#xff0c;實現非自回歸推理通過才氣張量的群-拓撲流形交叉注意力實現多模態推理&#xff0c;將輸入壓縮到低維空間持續迭代提出「條件計算提前終止」機制&#xff0c…

flink jobmanager離奇的heap oom

文章目錄 現象描述開始分析1.初步分析dump文件2.AI分析引用關系分析方向2.1 flink BlobServer bug分析方向2.2 和運行環境有關分析方向2.3 和任務有關 回到問題本身&#xff0c;思考一下1. seatunnel到底有沒有問題2.再次分析zipfile對象3.分析seatunnel es connector 源碼4 懷…