พาร์ติชันเท่ากับผลรวมย่อย (DP- 15) - อาร์เรย์ - บทช่วยสอน (2023)

4 กุมภาพันธ์ 2565 อาร์เรย์/โครงสร้างข้อมูล/การเขียนโปรแกรมแบบไดนามิก

ลิงค์ปัญหา:พาร์ทิชันเท่ากับผลรวมย่อย

เราได้รับอาร์เรย์ 'ARR' ที่มีจำนวนเต็มบวก N เราต้องค้นหาว่าเราสามารถแบ่งอาร์เรย์ออกเป็นสองส่วนย่อยเพื่อให้ผลรวมขององค์ประกอบของแต่ละส่วนย่อยเท่ากันหรือไม่

หากแบ่งพาร์ติชันได้ ให้คืนค่าจริงหรือคืนค่าเท็จ

ตัวอย่าง:พาร์ติชันเท่ากับผลรวมย่อย (DP- 15) - อาร์เรย์ - บทช่วยสอน (1)

ในตัวอย่างนี้ เมื่อเราสามารถแบ่งพาร์ติชันได้ เราจึงคืนค่าจริง

ข้อจำกัดความรับผิดชอบ:อย่ากระโดดไปที่วิธีแก้ปัญหาโดยตรง ลองใช้ตัวคุณเองก่อน

ข้อกำหนดเบื้องต้น: ผลรวมย่อยเท่ากับเป้าหมาย,การเรียกซ้ำในผลที่ตามมา

สารละลาย :

คำถามนี้เป็นการแก้ไขเล็กน้อยจากปัญหาที่กล่าวถึงในผลรวมย่อยเท่ากับเป้าหมาย. เราจำเป็นต้องแบ่งอาร์เรย์ (เช่น S) ออกเป็นสองส่วนย่อย (เช่น S1 และ S2) ตามคำถาม:

  • ผลรวมขององค์ประกอบของ S1 + ผลรวมขององค์ประกอบของ S2 = ผลรวมขององค์ประกอบของ S
  • ผลรวมขององค์ประกอบ S1 = ผลรวมขององค์ประกอบ S2

เงื่อนไขทั้งสองนี้หมายความว่า S1 = S2 = (S/2)

ตอนนี้,

  • ถ้า S (ผลรวมของอิลิเมนต์ของอินพุตอาร์เรย์) เป็นเลขคี่ ไม่มีทางที่เราจะแบ่งมันออกเป็นสองซีกเท่าๆ กัน ดังนั้นเราจึงคืนค่าเท็จได้
  • ถ้า S เป็นเลขคู่ เราต้องหาลำดับย่อยในอาร์เรย์อินพุตที่มีผลรวมเท่ากับ S/2 เพราะหากเราพบลำดับย่อยหนึ่งลำดับที่มีผลรวม S/2 องค์ประกอบที่เหลือจะเป็น S/2 โดยอัตโนมัติ ดังนั้นเราจึงแบ่งอาร์เรย์ที่กำหนดได้ ดังนั้นเราจึงคืนค่าจริง

บันทึก:ผู้อ่านควรดูวิดีโอนี้ “การเรียกซ้ำในผลที่ตามมา” เพื่อทำความเข้าใจวิธีที่เราสร้างลำดับที่ตามมาโดยใช้การเรียกซ้ำ

จากที่นี่เราจะพยายามหาลำดับที่ตามมาในอาร์เรย์ที่มี target = S/2 ตามที่กล่าวไว้ในผลรวมย่อยเท่ากับเป้าหมาย

ขั้นตอนในการสร้างโซลูชันแบบเรียกซ้ำ:

ก่อนอื่นเราจะสร้างวิธีแก้ปัญหาแบบเรียกซ้ำโดยจุดสามจุดที่กล่าวถึงในบทนำการเขียนโปรแกรมแบบไดนามิก.

ขั้นตอนที่ 1:แสดงปัญหาในรูปของดัชนี

อาร์เรย์จะมีดัชนี แต่มี "เป้าหมาย" อีกหนึ่งพารามิเตอร์ เราได้รับโจทย์เริ่มต้นเพื่อค้นหาว่ามีลำดับย่อยที่มีผลรวมเท่ากับเป้าหมายในอาร์เรย์ทั้งหมดหรือไม่

ดังนั้น เราสามารถพูดได้ว่าในขั้นต้น เราต้องหา (n-1, เป้าหมาย) ซึ่งหมายความว่าเราต้องค้นหาว่ามีลำดับย่อยในอาร์เรย์ตั้งแต่ดัชนี 0 ถึง n-1 ซึ่งมีผลรวมเท่ากับเป้าหมายหรือไม่ ในทำนองเดียวกัน เราสามารถทำให้เป็นภาพรวมสำหรับดัชนีใดๆ ได้ดังนี้:

พาร์ติชันเท่ากับผลรวมย่อย (DP- 15) - อาร์เรย์ - บทช่วยสอน (2)

กรณีฐาน:

  • ถ้าเป้าหมาย == 0 แสดงว่าเราพบผลลัพธ์ที่ตามมาจากขั้นตอนก่อนหน้าแล้ว เราจึงคืนค่าจริงได้
  • ถ้า ind==0 แสดงว่าเราอยู่ที่องค์ประกอบแรก ดังนั้นเราต้องส่งคืน arr[ind]==target หากองค์ประกอบเท่ากับเป้าหมาย เราจะคืนค่าจริงเป็นเท็จ

พาร์ติชันเท่ากับผลรวมย่อย (DP- 15) - อาร์เรย์ - บทช่วยสอน (3)

(Video) ใบแจ้งหนี้ที่ดีที่สุดที่ฉันเคยสร้างใน Excel! เรียนรู้วิธีสร้างมันด้วยตัวคุณเอง + ดาวน์โหลดฟรี

ขั้นตอนที่ 2:ลองใช้ตัวเลือกที่เป็นไปได้ทั้งหมดในดัชนีที่กำหนด

เราจำเป็นต้องสร้างผลที่ตามมาทั้งหมด เราจะใช้เทคนิคการเลือก/ไม่เลือกตามที่กล่าวไว้ในวิดีโอนี้”การเรียกซ้ำในผลที่ตามมา".

เรามีสองทางเลือก:

  • ยกเว้นองค์ประกอบปัจจุบันในลำดับต่อมา:ก่อนอื่น เราพยายามหาลำดับที่ตามมาโดยไม่พิจารณาองค์ประกอบดัชนีปัจจุบัน สำหรับสิ่งนี้ เราจะเรียกซ้ำไปยัง f(ind-1,target)
  • รวมองค์ประกอบปัจจุบันในผลที่ตามมา:เราจะพยายามหาลำดับที่ตามมาโดยพิจารณาดัชนีปัจจุบันเป็นองค์ประกอบเป็นส่วนหนึ่งของลำดับที่ตามมา เนื่องจากเราได้รวม arr[ind] เป้าหมายที่อัปเดตซึ่งเราต้องค้นหาในส่วนที่เหลือหากอาร์เรย์จะเป็นเป้าหมาย – arr[ind] ดังนั้น เราจะเรียก f(ind-1,target-arr[ind])

บันทึก:เราจะพิจารณาองค์ประกอบปัจจุบันในลำดับต่อมาก็ต่อเมื่อองค์ประกอบปัจจุบันน้อยกว่าหรือเท่ากับเป้าหมาย

พาร์ติชันเท่ากับผลรวมย่อย (DP- 15) - อาร์เรย์ - บทช่วยสอน (4)

ขั้นตอนที่ 3: ส่งคืน (ถ่าย || ไม่ถ่าย)

เนื่องจากเรากำลังมองหาเซตย่อยเพียงชุดเดียว หากเซตย่อยที่รับหรือไม่รับคืนค่าจริง เราก็สามารถคืนค่าจริงจากฟังก์ชันของเราได้ ดังนั้นเราจึงคืนค่า 'หรือ (||)' ของทั้งคู่

รหัสเทียมสุดท้ายหลังจากขั้นตอนที่ 1, 2 และ 3:

พาร์ติชันเท่ากับผลรวมย่อย (DP- 15) - อาร์เรย์ - บทช่วยสอน (5)

ขั้นตอนในการจดจำโซลูชันแบบเรียกซ้ำ:

ถ้าเราวาด recursion tree เราจะเห็นว่ามีปัญหาย่อยที่ทับซ้อนกัน ในการแปลงโซลูชันแบบเรียกซ้ำจะดำเนินการตามขั้นตอนต่อไปนี้:

  1. สร้างอาร์เรย์ dp ขนาด [n][k+1] ขนาดของอาร์เรย์อินพุตคือ 'n' ดังนั้นดัชนีจะอยู่ระหว่าง '0' และ 'n-1' เสมอ เป้าหมายสามารถรับค่าใดก็ได้ระหว่าง '0' ถึง 'k' ดังนั้นเราจึงใช้อาร์เรย์ dp เป็น dp[n][k+1]
  2. เราเริ่มต้นอาร์เรย์ dp เป็น -1
  3. เมื่อใดก็ตามที่เราต้องการหาคำตอบของพารามิเตอร์เฉพาะ (เช่น f(ind,target)) ก่อนอื่นเราจะตรวจสอบว่าคำตอบนั้นคำนวณไว้แล้วโดยใช้อาร์เรย์ dp หรือไม่ (เช่น dp[ind][target]!= -1 ) ถ้าใช่ ให้คืนค่าจากอาร์เรย์ dp
  4. ถ้าไม่ เรากำลังหาคำตอบสำหรับค่าที่กำหนดเป็นครั้งแรก เราจะใช้ความสัมพันธ์แบบเรียกซ้ำตามปกติ แต่ก่อนที่จะกลับจากฟังก์ชัน เราจะตั้งค่า dp[ind][target] เป็นคำตอบที่เราได้รับ

รหัส:

รหัส C++

#include โดยใช้เนมสเปซ std;bool subsetSumUtil(int ind, int target, vector& arr, vector> &dp){ if(target==0) return true; ถ้า (ind == 0) กลับ arr[0] == เป้าหมาย; if(dp[ind][target]!=-1) ส่งคืน dp[ind][target]; บูล notTaken = subsetSumUtil(ind-1,target,arr,dp); บูล = เท็จ; ถ้า(arr[ind]<=target) Take = subsetSumUtil(ind-1,target-arr[ind],arr,dp); ส่งคืน dp[ind][target]= notTaken||taken;}bool canPartition(int n, vector &arr){ int totSum=0; สำหรับ (int i=0; i> dp(n,เวกเตอร์(k+1,-1)); ส่งคืน subsetSumUtil(n-1,k,arr,dp); } }int main() { เวกเตอร์ arr = {2,3,3,3,4,5}; int n = arr.size(); if(canPartition(n,arr)) cout<<"อาร์เรย์สามารถแบ่งพาร์ติชันออกเป็นสองส่วนย่อยเท่าๆ กัน"; ศาลอื่น<<"อาร์เรย์ไม่สามารถแบ่งพาร์ติชันออกเป็นสองส่วนย่อยเท่าๆ กัน";}

เอาท์พุต:

อาร์เรย์สามารถแบ่งพาร์ติชันออกเป็นสองส่วนย่อยเท่าๆ กัน

ความซับซ้อนของเวลา: O(N*K) + O(N)

เหตุผล: มีสถานะ N*K ดังนั้นเมื่อสูงสุด 'N*K' ปัญหาใหม่จะได้รับการแก้ไข และเรากำลังเรียกใช้ for loop สำหรับ 'N' ครั้งเพื่อคำนวณผลรวมทั้งหมด

ความซับซ้อนของอวกาศ: O(N*K) + O(N)

เหตุผล: เรากำลังใช้ recursion stack space(O(N)) และ 2D array ( O(N*K))

รหัสจาวา

นำเข้า java.util.*;class TUF{static boolean subsetSumUtil(int ind, int target,int arr[],int[][] dp){ if(target==0) return true; ถ้า (ind == 0) กลับ arr[0] == เป้าหมาย; if(dp[ind][target]!=-1) ส่งคืน dp[ind][target]==0?false:true; บูลีน notTaken = subsetSumUtil(ind-1,target,arr,dp); บูลีนถ่าย = เท็จ; ถ้า(arr[ind]<=target) Take = subsetSumUtil(ind-1,target-arr[ind],arr,dp); dp[ind][target]=ไม่ถ่าย||ถ่ายแล้ว?1:0; กลับ notTaken||taken;}บูลีนคงที่ canPartition(int n,int[] arr){ int totSum=0; สำหรับ (int i=0; i

เอาท์พุต:

อาร์เรย์สามารถแบ่งพาร์ติชันออกเป็นสองส่วนย่อยเท่าๆ กัน

ความซับซ้อนของเวลา: O(N*K) + O(N)

(Video) เรียนรู้วิธีสร้างตัวกำหนดตารางเวลามุมมองแบบไดนามิกใน Excel Masterclass นี้ [School Manager Pt.11]

เหตุผล: มีสถานะ N*K ดังนั้นเมื่อสูงสุด 'N*K' ปัญหาใหม่จะได้รับการแก้ไข และเรากำลังเรียกใช้ for loop สำหรับ 'N' ครั้งเพื่อคำนวณผลรวมทั้งหมด

ความซับซ้อนของอวกาศ: O(N*K) + O(N)

เหตุผล: เรากำลังใช้ recursion stack space(O(N)) และ 2D array ( O(N*K))

รหัสหลาม

def subsetSumUtil(ind, target, arr, dp): if target == 0: return True ถ้า ind == 0: return arr[0] == target if dp[ind][target] != -1: return dp[ ind][target] notTaken = subsetSumUtil(ind-1, target, arr, dp) Taken = False if arr[ind] <= target: Taken = subsetSumUtil(ind-1, target-arr[ind], arr, dp) dp[ind][target] = notTaken หรือ Take return dp[ind][target]def canPartition(n, arr): totSum = sum(arr) if totSum % 2 == 1: return False else: k = totSum // 2 dp = [[-1 for i in range(k+1)] for j in range(n)] return subsetSumUtil(n-1, k, arr, dp)def main(): arr = [2, 3, 3, 3, 4, 5] n = len(arr) if canPartition(n, arr): พิมพ์("อาร์เรย์สามารถแบ่งพาร์ติชันออกเป็นสองส่วนย่อยเท่าๆ กัน") อื่น: พิมพ์("ไม่สามารถแบ่งอาร์เรย์ออกเป็นสองส่วนย่อยเท่าๆ กัน ") ถ้า __name__ == "__main__": main()

เอาท์พุต:

อาร์เรย์สามารถแบ่งพาร์ติชันออกเป็นสองส่วนย่อยเท่าๆ กัน

ความซับซ้อนของเวลา: O(N*K) + O(N)

เหตุผล: มีสถานะ N*K ดังนั้นเมื่อสูงสุด 'N*K' ปัญหาใหม่จะได้รับการแก้ไข และเรากำลังเรียกใช้ for loop สำหรับ 'N' ครั้งเพื่อคำนวณผลรวมทั้งหมด

ความซับซ้อนของอวกาศ: O(N*K) + O(N)

เหตุผล: เรากำลังใช้ recursion stack space(O(N)) และ 2D array ( O(N*K))

ขั้นตอนในการแปลง Recursive Solution เป็น Tabulation one

หากต้องการแปลงวิธีการบันทึกช่วยจำเป็นแบบตาราง ให้สร้างอาร์เรย์ dp ที่มีขนาดเดียวกับที่ทำในการบันทึกช่วยจำ เราสามารถตั้งค่าประเภทเป็นบูลและเริ่มต้นเป็นเท็จ

พาร์ติชันเท่ากับผลรวมย่อย (DP- 15) - อาร์เรย์ - บทช่วยสอน (6)

ขั้นแรก เราต้องเริ่มต้นเงื่อนไขพื้นฐานของโซลูชันแบบเรียกซ้ำ

  • หากเป้าหมาย == 0, ind สามารถรับค่าใดก็ได้ตั้งแต่ 0 ถึง n-1 ดังนั้น เราจำเป็นต้องตั้งค่าของคอลัมน์แรกเป็นจริง

พาร์ติชันเท่ากับผลรวมย่อย (DP- 15) - อาร์เรย์ - บทช่วยสอน (7)

  • แถวแรก dp[0][] ระบุว่ามีการพิจารณาเฉพาะองค์ประกอบแรกของอาร์เรย์ ดังนั้นสำหรับค่าเป้าหมายเท่ากับ arr[0] เฉพาะเซลล์ที่มีเป้าหมายนั้นเท่านั้นที่จะเป็นจริง ดังนั้นให้ตั้งค่า dp[0 อย่างชัดเจน ][arr[0]] =true, (dp[0][arr[0]] หมายความว่าเรากำลังพิจารณาองค์ประกอบแรกของอาร์เรย์โดยมีเป้าหมายเท่ากับองค์ประกอบแรกนั่นเอง) โปรดทราบว่าอาจเกิดขึ้นได้ที่ arr[0]>target ดังนั้นเราจึงตรวจสอบก่อน: if(arr[0]<=target) จากนั้นตั้งค่า dp[0][arr[0]] = true

พาร์ติชันเท่ากับผลรวมย่อย (DP- 15) - อาร์เรย์ - บทช่วยสอน (8)

  • หลังจากนั้น เราจะตั้งค่าซ้อนกันสำหรับลูปเพื่อสำรวจอาร์เรย์ dp และตามตรรกะที่กล่าวถึงในวิธีการเรียกซ้ำ เราจะตั้งค่าของแต่ละเซลล์ แทนที่จะเรียกซ้ำ เราจะใช้อาร์เรย์ dp เอง
  • สุดท้าย เราจะคืนค่า dp[n-1][k] เป็นคำตอบ

รหัส:

รหัส C++

#include โดยใช้เนมสเปซ std;bool canPartition(int n, vector &arr){ int totSum=0; สำหรับ (int i=0; i> dp(n,เวกเตอร์<บูล>(k+1,เท็จ)); สำหรับ (int i=0; i arr = {2,3,3,3,4,5}; int n = arr.size(); if(canPartition(n,arr)) cout<<"อาร์เรย์สามารถแบ่งพาร์ติชันออกเป็นสองส่วนย่อยเท่าๆ กัน"; ศาลอื่น<<"อาร์เรย์ไม่สามารถแบ่งพาร์ติชันออกเป็นสองส่วนย่อยเท่าๆ กัน";}

เอาท์พุต:

อาร์เรย์สามารถแบ่งพาร์ติชันออกเป็นสองส่วนย่อยเท่าๆ กัน

ความซับซ้อนของเวลา: O(N*K) +O(N)

(Video) 01 Knapsack Problem | Amazon Coding Interview | Dynamic programming | EP5

เหตุผล: มีลูปที่ซ้อนกันสองลูปที่อธิบาย O(N*K) และเมื่อเริ่มต้น เรากำลังเรียกใช้ for ลูปเพื่อคำนวณ totSum

ความซับซ้อนของอวกาศ: O(N*K)

เหตุผล: เรากำลังใช้อาร์เรย์ภายนอกขนาด 'N*K' Stack Space ถูกกำจัด

รหัสจาวา

นำเข้า java.util.*;class TUF{static boolean canPartition(int n,int[] arr){ int totSum=0; สำหรับ (int i=0; i

เอาท์พุต:

อาร์เรย์สามารถแบ่งพาร์ติชันออกเป็นสองส่วนย่อยเท่าๆ กัน

ความซับซ้อนของเวลา: O(N*K) +O(N)

เหตุผล: มีลูปที่ซ้อนกันสองลูปที่อธิบาย O(N*K) และเมื่อเริ่มต้น เรากำลังเรียกใช้ for ลูปเพื่อคำนวณ totSum

ความซับซ้อนของอวกาศ: O(N*K)

เหตุผล: เรากำลังใช้อาร์เรย์ภายนอกขนาด 'N*K' Stack Space ถูกกำจัด

รหัสหลาม

def canPartition(n, arr): totSum = sum(arr) if totSum % 2 == 1: return False else: k = totSum // 2 dp = [[False for j in range(k + 1)] for i in range(n)] for i in range(n): dp[i][0] = True if arr[0] <= k: dp[0][arr[0]] = True for ind in range(1, n): สำหรับเป้าหมายในระยะ (1, k + 1): notTaken = dp[ind - 1][target] Taken = False if arr[ind] <= target: Taken = dp[ind - 1][target - arr [ind]] dp[ind][target] = ไม่ถ่ายหรือรับคืน dp[n - 1][k]def main(): arr = [2,3,3,3,4,5] n = len(arr ) if canPartition(n, arr): print("อาร์เรย์สามารถแบ่งพาร์ติชันออกเป็นสองส่วนย่อยเท่าๆ กัน") อื่น: พิมพ์("อาร์เรย์ไม่สามารถแบ่งพาร์ติชันออกเป็นสองส่วนย่อยเท่าๆ กัน")if __name__ == '__main__': main()

เอาท์พุต:

อาร์เรย์สามารถแบ่งพาร์ติชันออกเป็นสองส่วนย่อยเท่าๆ กัน

ความซับซ้อนของเวลา: O(N*K) +O(N)

เหตุผล: มีลูปที่ซ้อนกันสองลูปที่อธิบาย O(N*K) และเมื่อเริ่มต้น เรากำลังเรียกใช้ for ลูปเพื่อคำนวณ totSum

ความซับซ้อนของอวกาศ: O(N*K)

เหตุผล: เรากำลังใช้อาร์เรย์ภายนอกขนาด 'N*K' Stack Space ถูกกำจัด

ส่วนที่ 3: การเพิ่มประสิทธิภาพพื้นที่

ถ้าเราดูความสัมพันธ์อย่างใกล้ชิด

dp[ind][เป้าหมาย] = dp[ind-1][เป้าหมาย] || dp[ind-1][target-arr[ind]]

เราเห็นว่าในการคำนวณค่าของเซลล์ของอาร์เรย์ dp เราต้องการเฉพาะค่าของแถวก่อนหน้า (เช่น prev) ดังนั้นเราจึงไม่จำเป็นต้องจัดเก็บอาร์เรย์ทั้งหมด ดังนั้นเราจึงสามารถปรับพื้นที่ให้เหมาะสมได้

บันทึก:เมื่อใดก็ตามที่เราสร้างแถวใหม่ (พูด cur) เราต้องตั้งค่าให้องค์ประกอบแรกเป็นจริงตามเงื่อนไขฐานของเราอย่างชัดเจน

(Video) เรียนรู้วิธีส่งและรับอีเมล Gmail จาก Excel - (รวมไฟล์แนบ) [พร้อมดาวน์โหลดฟรี]

รหัส:

รหัส C++

#include โดยใช้เนมสเปซ std;bool canPartition(int n, vector &arr){ int totSum=0; สำหรับ (int i=0; i ก่อนหน้า (k+1,เท็จ); ก่อนหน้า[0] = จริง; ถ้า(arr[0]<=k) ก่อนหน้า[arr[0]] = จริง; สำหรับ (int ind = 1; ind cur(k+1,false); เคอร์[0] = จริง; สำหรับ (int target= 1; target<=k; target++){ บูล notTaken = ก่อนหน้า[เป้าหมาย]; บูล = เท็จ; ถ้า(arr[ind]<=target) Take = ก่อนหน้า[target-arr[ind]]; cur[target]= ไม่ถ่าย||ถ่ายแล้ว; } ก่อนหน้า = เคอร์; } กลับก่อนหน้า [k]; } }int main() { เวกเตอร์ arr = {2,3,3,3,4,5}; int n = arr.size(); if(canPartition(n,arr)) cout<<"อาร์เรย์สามารถแบ่งพาร์ติชันออกเป็นสองส่วนย่อยเท่าๆ กัน"; ศาลอื่น<<"อาร์เรย์ไม่สามารถแบ่งพาร์ติชันออกเป็นสองส่วนย่อยเท่าๆ กัน";}

เอาท์พุต:

Array สามารถแบ่งออกเป็นสองส่วนย่อยเท่า ๆ กัน

ความซับซ้อนของเวลา: O(N*K) +O(N)

เหตุผล: มีลูปที่ซ้อนกันสองลูปที่อธิบาย O(N*K) และเมื่อเริ่มต้น เรากำลังเรียกใช้ for ลูปเพื่อคำนวณ totSum

ความซับซ้อนของอวกาศ: O(K)

เหตุผล: เรากำลังใช้อาร์เรย์ภายนอกขนาด 'K+1' เพื่อจัดเก็บเพียงแถวเดียว

รหัสจาวา

นำเข้า java.util.*;class TUF{static boolean canPartition(int n,int[] arr){ int totSum=0; สำหรับ (int i=0; i

เอาท์พุต:

Array สามารถแบ่งออกเป็นสองส่วนย่อยเท่า ๆ กัน

ความซับซ้อนของเวลา: O(N*K) +O(N)

เหตุผล: มีลูปที่ซ้อนกันสองลูปที่อธิบาย O(N*K) และเมื่อเริ่มต้น เรากำลังเรียกใช้ for ลูปเพื่อคำนวณ totSum

ความซับซ้อนของอวกาศ: O(K)

เหตุผล: เรากำลังใช้อาร์เรย์ภายนอกขนาด 'K+1' เพื่อจัดเก็บเพียงแถวเดียว

รหัสหลาม

def canPartition(n, arr): totSum = sum(arr) if totSum % 2 == 1: return False else: k = totSum // 2 prev = [False] * (k + 1) prev[0] = True if arr[0] <= k: ก่อนหน้า[arr[0]] = True สำหรับ ind in range(1, n): cur = [False] * (k + 1) cur[0] = True สำหรับเป้าหมายในช่วง(1 , k + 1): notTaken = ก่อนหน้า[เป้าหมาย] ถ่าย = False ถ้า arr[ind] <= เป้าหมาย: ถ่าย = ก่อนหน้า[เป้าหมาย - arr[ind]] cur[target] = ไม่ถ่ายหรือถ่ายก่อนหน้า = เคอร์ส่งคืนค่าก่อนหน้า[k ]def main(): arr = [2, 3, 3, 3, 4, 5] n = len(arr) if canPartition(n, arr): print("อาร์เรย์สามารถแบ่งพาร์ติชันออกเป็นสองส่วนย่อยเท่าๆ กัน") อื่น : พิมพ์ ("ไม่สามารถแบ่งอาร์เรย์ออกเป็นสองส่วนย่อยเท่า ๆ กัน")if __name__ == "__main__": main()

เอาท์พุต:

Array สามารถแบ่งออกเป็นสองส่วนย่อยเท่า ๆ กัน

ความซับซ้อนของเวลา: O(N*K) +O(N)

เหตุผล: มีลูปที่ซ้อนกันสองลูปที่อธิบาย O(N*K) และเมื่อเริ่มต้น เรากำลังเรียกใช้ for ลูปเพื่อคำนวณ totSum

ความซับซ้อนของอวกาศ: O(K)

(Video) Blox Fruits : ฟาร์ม Level 1-500 เปลี่ยนผลทุกๆ 50 จะเกลือหรือเปล่า!!!!

เหตุผล: เรากำลังใช้อาร์เรย์ภายนอกขนาด 'K+1' เพื่อจัดเก็บเพียงแถวเดียว

ขอขอบคุณเป็นพิเศษกับอันชูมาน ชาร์มาและอุบาสิกา สำหรับบทความเกี่ยวกับ takeUforward นี้ หากคุณต้องการแบ่งปันความรู้ของคุณกับกลุ่ม TakeUforwardโปรดตรวจสอบบทความนี้

Videos

1. Blox Fruits สูตรโกงหาผลปีศาจ ได้โคตรง่ายผลดทพๆจะออกไหม [ โลก1 ]
(THE AUN GAME)
2. Basic BGP by KoChaiwat (from Live)
(Chaiwat Amornhirunwong)
3. Uwe L Korn - Efficient and portable DataFrame storage with Apache Parquet
(PyData)
4. เรียนพื้นฐานการทำวิจัยตลาดออนไลน์ด้วย Google Forms และ Google Sheets
(DataRockie)
5. คณิตศาสตร์ ม.2 กลุ่มPrivate เทอม1 การบวก ลบ คูณ หาร พหุนาม
(ครูพี่กาย โรงเรียนกวดวิชาวิคเตอร์)
6. (LIVE) OnDemand Success Live พี่ทอล์ค น้องโทร | [Ep.15] โอปป้าฟิสิกส์ RETURN !!
(ondemandacademy)

References

Top Articles
Latest Posts
Article information

Author: Lidia Grady

Last Updated: 10/12/2023

Views: 5235

Rating: 4.4 / 5 (45 voted)

Reviews: 84% of readers found this page helpful

Author information

Name: Lidia Grady

Birthday: 1992-01-22

Address: Suite 493 356 Dale Fall, New Wanda, RI 52485

Phone: +29914464387516

Job: Customer Engineer

Hobby: Cryptography, Writing, Dowsing, Stand-up comedy, Calligraphy, Web surfing, Ghost hunting

Introduction: My name is Lidia Grady, I am a thankful, fine, glamorous, lucky, lively, pleasant, shiny person who loves writing and wants to share my knowledge and understanding with you.