Python算法題集_組合總和

?Python算法題集_組合總和

  • 題39:組合總和
  • 1. 示例說明
  • 2. 題目解析
    • - 題意分解
    • - 優化思路
    • - 測量工具
  • 3. 代碼展開
    • 1) 標準求解【值傳遞+回溯】
    • 2) 改進版一【引用傳遞+堆棧回溯】
    • 3) 改進版二【過程值列表緩存+遍歷后檢索】
  • 4. 最優算法
  • 5. 相關資源

本文為Python算法題集之一的代碼示例

題39:組合總和

1. 示例說明

  • 給你一個 無重復元素 的整數數組 candidates 和一個目標整數 target ,找出 candidates 中可以使數字和為目標數 target 的 所有 不同組合 ,并以列表形式返回。你可以按 任意順序 返回這些組合。

    candidates 中的 同一個 數字可以 無限制重復被選取 。如果至少一個數字的被選數量不同,則兩種組合是不同的。

    對于給定的輸入,保證和為 target 的不同組合數少于 150 個。

    示例 1:

    輸入:candidates = [2,3,6,7], target = 7
    輸出:[[2,2,3],[7]]
    解釋:
    2 和 3 可以形成一組候選,2 + 2 + 3 = 7 。注意 2 可以使用多次。
    7 也是一個候選, 7 = 7 。
    僅有這兩種組合。
    

    示例 2:

    輸入: candidates = [2,3,5], target = 8
    輸出: [[2,2,2,2],[2,3,3],[3,5]]
    

    示例 3:

    輸入: candidates = [2], target = 1
    輸出: []
    

    提示:

    • 1 <= candidates.length <= 30
    • 2 <= candidates[i] <= 40
    • candidates 的所有元素 互不相同
    • 1 <= target <= 40

2. 題目解析

- 題意分解

  1. 本題是計算多個集合之間的求和問題,每個集合由若干個同樣的整數組成
  2. 同樣整數和不能超過target,所以多個集合都是有限集合,因此每個集合能合成出來的數值也是有限的,可以用回溯法求解
  3. 回溯法(探索與回溯法)是一種選優搜索法,又稱為試探法,按選優條件向前搜索,以達到目標。但當探索到某一步時,發現原先選擇并不優或達不到目標,就退回一步重新選擇,這種走不通就退回再走的技術為回溯法。

- 優化思路

  1. 通常優化:減少循環層次

  2. 通常優化:增加分支,減少計算集

  3. 通常優化:采用內置算法來提升計算速度

  4. 分析題目特點,分析最優解

    1. 可以在回溯算法中使用值傳遞

    2. 可以在回溯算法中使用引用傳遞,但是應用傳遞必須解決回退操作,可以使用堆棧結構

    3. 可以考慮存儲過程值列表,最后將等于target的集合返回


- 測量工具

  • 本地化測試說明:LeetCode網站測試運行時數據波動很大【可把頁面視為功能測試】,因此需要本地化測試解決數據波動問題
  • CheckFuncPerf(本地化函數用時和內存占用測試模塊)已上傳到CSDN,地址:Python算法題集_檢測函數用時和內存占用的模塊
  • 本題本地化超時測試用例自己生成,詳見章節【最優算法】,代碼文件包含在【相關資源】中

3. 代碼展開

1) 標準求解【值傳遞+回溯】

使用列表作為值傳遞參數,逐層遞歸,完成回溯

頁面功能測試,馬馬虎虎,超過40%在這里插入圖片描述

import CheckFuncPerf as cfpclass Solution:def combinationSum_base(self, candidates, target):def bracktracing(candidates, begin, ilen, path, ret, target):if target < 0:returnif target == 0:ret.append(path)returnfor iIdx in range(begin, ilen):bracktracing(candidates, iIdx, ilen, path + [candidates[iIdx]], ret, target - candidates[iIdx])ilen = len(candidates)path, result = [], []if ilen == 0:return resultbracktracing(candidates, 0, ilen, path, result, target)return resultaSolution = Solution()
result = cfp.getTimeMemoryStr(aSolution.combinationSum_base, nums, target)
print(result['msg'], '執行結果 = {}'.format(len(result['result'])))# 運行結果
函數 combinationSum_base 的運行時間為 1076.25 ms;內存使用量為 12060.00 KB 執行結果 = 62271

2) 改進版一【引用傳遞+堆棧回溯】

使用列表作為引用傳遞參數,逐層遞歸,完成回溯

頁面功能測試,馬馬虎虎,超越71%在這里插入圖片描述

import CheckFuncPerf as cfpclass Solution:def combinationSum_ext1(self, candidates, target):candidates.sort()path, result = [], []idx, isum = 0, 0def bracktracing(idx, isum, path):if sum(path) == target:result.append(path[:])returnfor jIdx in range(idx, len(candidates)):if isum + candidates[jIdx] > target:returnpath.append(candidates[jIdx])isum += candidates[jIdx]bracktracing(jIdx, isum, path)path.pop()isum -= candidates[jIdx]bracktracing(idx, isum, path)return resultaSolution = Solution()
result = cfp.getTimeMemoryStr(aSolution.combinationSum_base, nums, target)
print(result['msg'], '執行結果 = {}'.format(len(result['result'])))# 運行結果
函數 combinationSum_base 的運行時間為 1076.25 ms;內存使用量為 12060.00 KB 執行結果 = 62271

3) 改進版二【過程值列表緩存+遍歷后檢索】

使用多維列表結構保存各數值對應的組合列表,遍歷完成后下標檢索對應組合列表

頁面功能測試,馬馬虎虎,超過23%在這里插入圖片描述

import CheckFuncPerf as cfpclass Solution:def combinationSum_ext2(self, candidates, target):import copycandidates.sort()dp = [[] for x in range(target + 1)]for candidate in candidates:for iIdx in range(candidate, target + 1):if candidate == iIdx:dp[iIdx].append([candidate])else:for combination in dp[iIdx - candidate]:tmpgroup = copy.deepcopy(combination)tmpgroup.append(candidate)dp[iIdx].append(tmpgroup)return dp[target]aSolution = Solution()
result = cfp.getTimeMemoryStr(aSolution.combinationSum_base, nums, target)
print(result['msg'], '執行結果 = {}'.format(len(result['result'])))# 運行結果
函數 combinationSum_base 的運行時間為 1076.25 ms;內存使用量為 12060.00 KB 執行結果 = 62271

4. 最優算法

根據本地日志分析,最優算法為第1種方式【值傳遞+回溯】combinationSum_base

本題測試數據,似乎能推出以下結論:

  1. 組合的回溯求解中,值傳遞性能優于引用傳遞的堆棧結構
  2. 內存對象過多后,性能下降明顯,如combinationSum_ext2
nums = [x for x in range(10, 20)]
target = 200
aSolution = Solution()
result = cfp.getTimeMemoryStr(aSolution.combinationSum_base, nums, target)
print(result['msg'], '執行結果 = {}'.format(len(result['result'])))
result = cfp.getTimeMemoryStr(aSolution.combinationSum_ext1, nums, target)
print(result['msg'], '執行結果 = {}'.format(len(result['result'])))
result = cfp.getTimeMemoryStr(aSolution.combinationSum_ext2, nums, target)
print(result['msg'], '執行結果 = {}'.format(len(result['result'])))# 算法本地速度實測比較
函數 combinationSum_base 的運行時間為 1076.25 ms;內存使用量為 12060.00 KB 執行結果 = 62271
函數 combinationSum_ext1 的運行時間為 1243.29 ms;內存使用量為 11848.00 KB 執行結果 = 62271
函數 combinationSum_ext2 的運行時間為 14627.27 ms;內存使用量為 16080.00 KB 執行結果 = 62271

5. 相關資源

本文代碼已上傳到CSDN,地址:Python算法題源代碼_LeetCode(力扣)_組合總和

一日練,一日功,一日不練十日空

may the odds be ever in your favor ~

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

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

相關文章

.halo勒索病毒的最新威脅:如何恢復您的數據?

尊敬的讀者&#xff1a; 隨著科技的發展&#xff0c;網絡安全已經成為我們日常生活中不可忽視的重要議題。其中&#xff0c;勒索病毒是當前網絡安全威脅中的一大挑戰&#xff0c;而“.halo”勒索病毒更是近期備受關注的惡意軟件之一。本文將介紹關于“.halo”勒索病毒的背景知…

AI新工具(20240227) StickerBaker文本生成貼紙的工具;Mistral Large;Rewind等

StickerBaker - 基于Replicate和Fly.io技術&#xff0c;100%開源的制作貼紙的工具 StickerBaker是一個基于人工智能的貼紙創作工具&#xff0c;允許用戶通過輸入特定的提示語句生成獨特的貼紙。這個工具使用了Replicate平臺來生成貼紙&#xff0c;同時依托于Fly.io作為其基礎設…

算法項目外包的收費方式

針對算法研究性項目的收費方式和注意事項&#xff0c;這取決于項目的具體性質、規模和所涉及的技術領域。以下是一些常見的收費方式和需要注意的問題&#xff0c;希望對大家有所幫助。北京木奇移動技術有限公司&#xff0c;專業的軟件外包開發公司&#xff0c;歡迎交流合作。 收…

Python學習DAY09_文件和異常

文件和異常 實際開發中常常會遇到對數據進行持久化操作的場景&#xff0c;而實現數據持久化最直接簡單的方式就是將數據保存到文件中。 在 Python 中實現文件的讀寫操作其實非常簡單&#xff0c;通過 Python 內置的 open 函數&#xff0c;我們可以指定文件名、操作模式、編碼信…

1552.平衡二叉樹

輸入格式 第一行包含整數 N&#xff0c;表示總插入值數量。第二行包含 N 個不同的整數&#xff0c;表示每個插入值。 輸出格式 輸出得到的 AVL 樹的根是多少。 數據范圍 1≤N≤20 輸入樣例1&#xff1a; 5 88 70 61 96 120 輸出樣例1&#xff1a; 70 輸入樣例2&#xff1a…

商業江湖大揭秘:月入千萬與顆粒無收,究竟差了什么?

在商業的浩瀚江湖 英雄豪杰們或乘風破浪、月入千萬&#xff0c;或步履蹣跚、顆粒無收&#xff0c;這背后的奧秘究竟何在&#xff1f;是天意難測&#xff0c;還是人為疏忽&#xff1f;是制度的不完善&#xff0c;還是工具的滯后不前&#xff1f;答案就隱藏在你未曾注意的細節之…

公司招嵌入式開發崗位,為什么感覺一年比一年難?

最近看到一個問題&#xff1a; 是一個HR在吐槽招不到嵌入式開發的人才。 這句話&#xff0c;難免會誤導一些想入行嵌入式的同學&#xff0c;臥槽&#xff0c;這么缺人?趕緊沖&#xff01; 哼次哼次學完一堆技術棧&#xff0c;一投簡歷&#xff0c;一個面試機會都沒有。 這就是…

24路電磁鎖主板在智能存儲系統中的作用

在無人值守場景中&#xff0c;如自助服務機、智能生鮮柜、共享儲物柜等&#xff0c;使用24路電磁鎖主板可以集成身份識別技術&#xff0c;將用戶的驗證結果轉化為相應的開鎖動作&#xff0c;提升用戶體驗和運營效率&#xff0c;是實現智能存儲系統高效、安全和自動化運行的關鍵…

Kubernetes的五大開源存儲項目

在Kubernetes中&#xff0c;關于數據的持久化管理是一種挑戰&#xff0c;對此&#xff0c;社區提供了多種存儲的解決方案&#xff0c;這些方案旨在簡化和優化容器化應用程序的持久化數據管理。 現介紹 Kubernetes 的五大開源存儲項目&#xff0c;帶你了解開源存儲解決方案的多…

unity后期

unity|后處理篇 前言一、Post-Processing 1、 Post-Processing的使用2、Post-Processing后處理效果 抗鋸齒①、Ambient Occlusion 環境光遮蔽②、Auto Exposure 自動曝光③、Bloom 輝光/泛光④、Chromatic Aberration | 色差⑤、Color Grading 色調/顏色分級⑥、Depth Of Fiel…

銳捷網絡攜數據中心、以太全光等創新解決方案亮相2024MWC

在西班牙巴塞羅那舉行的2024年世界移動通信大會(MWC)上,銳捷網絡(下文簡稱“銳捷”)展示了將技術與應用充分融合的云數據中心、5G、光網絡等產品及解決方案,幫助更多行業組織建設更貼近業務、智能、簡單、高效、綠色低碳的網絡基礎設施,應對當下及未來的挑戰,共同連接更廣闊可能…

PHP語言常見面試題:請解釋一下PHP是什么,以及它的主要用途是什么?

PHP&#xff0c;英文全稱為Hypertext Preprocessor&#xff0c;中文名稱為“超文本預處理器”。它是一種通用的開源腳本語言&#xff0c;特別適用于Web開發領域。PHP最初是由Rasmus Lerdorf在1995年創建的&#xff0c;并且自那時以來&#xff0c;它已經發展成為一個功能強大且易…

骨傳導耳機好用嗎?六大選購法則與避坑技巧大公開

在過去的兩年里&#xff0c;骨傳導耳機逐漸成為大眾的新寵&#xff0c;這一趨勢并不出人意料。畢竟長時間使用音量過大的傳統入耳式耳機&#xff0c;多多少少會對我們的聽力健康構成威脅。然而不同耳機對聽力的潛在影響程度是有差異的。骨傳導耳機好用嗎&#xff1f;與傳統耳機…

租床小程序|租床系統|租賃軟件開發功能

隨著移動互聯網的普及&#xff0c;越來越多的人開始選擇在線上完成各種租賃業務&#xff0c;而醫院租床也不例外。在這個趨勢下&#xff0c;開發一款租賃小程序成為了市場的必然需求。 租床小程序的功能 1、搜索與篩選 為了滿足不同用戶的需求&#xff0c;小程序應該提供設備…

android適配器adapter,Android程序員架構之路該如何繼續學習

便于開發的插件、工具和第三方開源庫 1.GsonFormat 使用方法&#xff1a;快捷鍵AltS也可以使用AltInsert選擇GsonFormat&#xff0c;作用&#xff1a;速將json字符串轉換成一個Java Bean&#xff0c;免去我們根據json字符串手寫對應Java Bean的過程。 2.ButterKnife Zelezny …

vmware16 nat模式 經常掉線 需要重啟nat

vmware16 nat模式 經常掉線 需要重啟nat才能聯網&#xff0c;之后又過一會掉線&#xff0c;往復操作重啟nat. 修復方案&#xff08;待驗證&#xff09; 修改靜態ip 嘗試過的方案&#xff08;無效果&#xff09; 一 調整 MaxUserPort 和 TcpTimedWaitDelay 設置 連接&#xf…

關于Node.js異常處理的教程

在Node.js開發中&#xff0c;異常處理是非常重要的一部分。良好的異常處理可以幫助我們及時發現和解決問題&#xff0c;提高系統的穩定性和可靠性。本教程將向您介紹Node.js中異常處理的最佳實踐和策略。 1. 使用try-catch捕獲同步異常 在Node.js中&#xff0c;可以使用try-c…

【Linux C | 網絡編程】getaddrinfo 函數詳解及C語言例子

&#x1f601;博客主頁&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客內容&#x1f911;&#xff1a;&#x1f36d;嵌入式開發、Linux、C語言、C、數據結構、音視頻&#x1f36d; &#x1f923;本文內容&#x1f923;&a…

element-plus 的el-img組件訪問oss圖片自動拼接前端地址

這是我的組件代碼 <el-image style"width: 100px; height: 100px" :src"scope.row.logo" />訪問時候 竟然憑借上了前端的地址端口 原來是我的oss服務是使用了域名做cdn加速的 內容分發網絡&#xff08;CDN&#xff09;或者服務器配置&#xff0c;可…

k8s學習-數據管理之nfs手動搭建

需要先準備好3臺虛擬機 系統CentOS7 IP 192.168.200.128 master IP 192.168.200.129 node1 IP 192.168.200.130 node2 問題描述 在學習數據管理的時候創建完pv和pvc以后&#xff0c;創建了pod使用pvc&#xff0c;但是pod創建不成功。 查看pod描述 kubectl describe pod myp…