Tập hợp con mảng giải pháp hackerrank python

Vấn đề SUBSET-SUM liên quan đến việc xác định xem một tập hợp con từ danh sách các số nguyên có thể tính tổng thành một giá trị đích hay không. Ví dụ: xem xét danh sách

nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
4. Nếu
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
5, có hai tập hợp con đạt được tổng này.
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
6 và
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
0. Nếu
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
1, không có giải pháp nào

Nói chung, việc xác định xem có bất kỳ giải pháp nào cho SUBSET-SUM hay không là NP-hard. nếu có

nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
2 số nguyên trong danh sách
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
3 thì tồn tại
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
4 tập con cần kiểm tra (không bao gồm tập rỗng). Trong bài viết này, chúng ta sẽ xem xét một phương pháp giải hiệu quả hơn bằng quy hoạch động (DP). Tuy nhiên, không giống như hầu hết các hướng dẫn, chúng tôi không chỉ xác định xem có tồn tại giải pháp hay không mà chúng tôi sẽ xem cách khám phá tất cả các giải pháp. Thuật toán hoạt động với các giá trị đầu vào âm và dương, cũng như lặp lại các số nguyên không duy nhất trong
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
3

TLDR;

Tìm kiếm một giải pháp nhanh chóng và không nhất thiết muốn biết các chi tiết cơ bản? .

nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
6

Logic của bộ giải được triển khai trong C++ và sử dụng Pybind11 để hiển thị giao diện Python. Mã nguồn có sẵn trên GitHub

1. Sơ chế

Trước khi đi vào giải pháp DP, chúng tôi sẽ áp dụng một số tiền xử lý cho đầu vào của vấn đề (

nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
3 và
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
8)

Lật dấu 🔄

Điều đầu tiên chúng ta sẽ làm là đổi dấu của tất cả các số nguyên trong

nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
3 cũng như
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
8, nếu mục tiêu là số âm. Điều này đảm bảo rằng
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
8 của chúng ta sẽ luôn bằng 0 hoặc lớn hơn, điều này giúp cho toàn bộ thuật toán trở nên dễ dàng hơn. Ta có thể làm việc này mà không cần lo lắng, vì nghiệm trước và sau khi lật dấu là tương đương nhau

nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
2

Sắp xếp các số ➡️

Bước tiền xử lý tiếp theo là sắp xếp

nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
3 theo thứ tự tăng dần, điều này cần thiết để thuật toán DP hoạt động (được mô tả sau). Nếu bạn cần nhớ thứ tự ban đầu của
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
3, bạn có thể thực hiện một argsort để ánh xạ từ vị trí hiện tại của một số nguyên trong danh sách tới vị trí của nó trong danh sách đã sắp xếp. Sau đó, bạn luôn có thể ánh xạ lại vị trí ban đầu nếu cần

nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]

Kiểm tra xem mục tiêu quá thấp hay quá cao 🛑

Xem xét trường hợp

nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
64. Số tiền nhỏ nhất có thể đạt được là gì? . số tiền lớn nhất có thể là gì? . Nếu tổng của
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
8 nhỏ hơn tổng của tất cả các số nguyên âm trong
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
3 hoặc lớn hơn tổng của tất cả các số nguyên dương trong
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
3 thì không có nghiệm nào tồn tại

Chúng tôi sẽ lưu trữ tổng của tất cả các số nguyên âm trong biến

nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
68 và tổng của tất cả các số nguyên dương trong biến
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
69. Nếu
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
20 hoặc
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
21, chúng ta có thể dừng sớm với “Không có giải pháp. ”

2. Lập trình năng động

Ảnh của Mika Baumeister trên Bapt

Khi quá trình tiền xử lý hoàn tất, chúng ta đã sẵn sàng điền vào bảng lập trình động có tên là

nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
22. Bảng
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
22 sẽ có
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
2 hàng (đã cho số
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
2) và
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
26 cột. Các giá trị được lưu trữ trong bảng sẽ đơn giản là Đúng hoặc Sai. Chỉ số hàng và cột bắt đầu từ 0

  • Nếu chúng tôi đang ở trên
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    27, thì chúng tôi đang xem xét tất cả các tập hợp con sử dụng các số nguyên cho đến và bao gồm số nguyên thứ
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    8 trong
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    3 đã sắp xếp. Số nguyên thứ
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    28 không cần đưa vào, nhưng nó “có sẵn” nếu chúng ta muốn sử dụng nó
  • Nếu chúng tôi đang ở trên
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    31, chúng tôi đang cố gắng tìm các tập hợp con có tổng bằng một mục tiêu "trung gian" là
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    32. Lưu ý rằng vì chúng tôi có
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    26 cột, giá trị cuối cùng của
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    34 sẽ là
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    35, nghĩa là cuối cùng, chúng tôi cố gắng tìm các tập hợp con có tổng bằng
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    36
  • Vì vậy,
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    37 có nghĩa là tồn tại một tập hợp con trong
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    38 có tổng bằng
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    32. Nếu
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    20 thì không tồn tại tập con như vậy
  • Khôi phục giải pháp. nếu
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    21, tồn tại một tập hợp con của
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    3 có tổng bằng
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    8

Quy tắc cập nhật ⭐️

Chúng tôi bắt đầu bằng cách khởi tạo bảng

nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
22 bằng các số 0 và điền vào hàng đầu tiên của
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
22, lưu ý rằng
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
26 chỉ có thể là 1 nếu
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
27 bằng với
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
32

nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
6

Đối với các hàng còn lại,

nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
29 có thể được đánh dấu 1 trong các tình huống sau

  • nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    30. Nếu mục tiêu “trung gian”
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    32 có thể đạt được chỉ bằng cách sử dụng một tập hợp con từ
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    32 thì rõ ràng, mục tiêu đó cũng có thể đạt được nếu số thứ
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    28 được phép nằm trong tập hợp con
  • nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    34. Trong trường hợp này, mục tiêu trung gian
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    32 có thể đạt được từ một tập hợp con với một số nguyên duy nhất.
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    36
  • nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    37. Quy tắc khó nhất, gợi nhớ đến các giải pháp quy hoạch động cho vấn đề về chiếc ba lô. Nếu tồn tại một tập hợp con của
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    32 có tổng bằng
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    39, thì chúng ta biết rằng cũng có một tập hợp con có tổng bằng
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    32 bằng cách thêm
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    41 vào tập hợp con
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
2

Độ phức tạp về thời gian và không gian ⏱

Giải pháp DP được mô tả ở đây được gọi là thuật toán giả đa thức. Kích thước của bảng DP không chỉ phụ thuộc (tuyến tính) vào số phần tử trong

nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
3, mà còn (tuyến tính) vào các giá trị của
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
3 và
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
8, vì số lượng cột trong bảng là khoảng cách giữa
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
8 và tổng

Mỗi ô của bảng phải được đặt thành 0 hoặc 1 một lần và điều này được xác định bằng cách sử dụng một số lượng truy vấn không đổi đến các ô khác, do đó, thời gian chạy của thuật toán chia tỷ lệ bằng với kích thước bảng

DP có khuyết điểm, vũ phu có thể tốt hơn 💪

Giả sử

nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
47 và
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
48. Sử dụng phương pháp DP, chúng ta sẽ có 2 hàng và
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
49 cột. Đó là rất nhiều sử dụng bộ nhớ cho một vấn đề rõ ràng không thể giải quyết. Nếu có ít số trong
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
3 nhưng phạm vi giá trị lớn, tốt hơn hết bạn nên kiểm tra mạnh tay tất cả các tập hợp con có thể

3. Tìm mọi giải pháp 🤯

Chúng tôi sẽ sử dụng ngăn xếp, nhưng tiếc là không phải loại ngăn xếp này. Ảnh của Brigitte Tohm trên Bapt

Hãy chuyển sang chủ đề có lẽ là thách thức nhất và cũng là chủ đề ít được thảo luận nhất trong các hướng dẫn khác. cách thực sự tìm tập hợp con nào đạt được tổng

nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
8

Để làm điều này, chúng tôi cần sử dụng bảng

nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
22 của mình và quay lại qua nó. Chúng tôi sẽ sử dụng một kỹ thuật không đệ quy. một chồng. Mỗi mục trong ngăn xếp sẽ là một cấu trúc dữ liệu đơn giản mà tôi gọi là
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
53

nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
3

Bây giờ chúng tôi biết, tồn tại một giải pháp nếu ô dưới cùng bên phải của bảng

nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
22 là 1. Mặt khác, thậm chí đừng cố gắng tìm giải pháp, bởi vì không có bất kỳ giải pháp nào. Chúng tôi sẽ khởi tạo ngăn xếp / quay lui bằng cách bắt đầu từ ô dưới cùng bên phải. Chúng tôi giả sử rằng số nguyên cuối cùng trong
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
3 được bao gồm trong tập hợp con, vì vậy,
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
56 sẽ là giá trị của
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
8 trừ đi
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
58

nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
2

Bây giờ chúng tôi liên tục bật các mục từ ngăn xếp và thêm các mục mới cho đến khi nó trống. Sau khi hoàn thành, chúng tôi sẽ liệt kê tất cả các giải pháp có thể

Hãy xem xét rằng chúng tôi vừa xuất hiện một mục.

nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
59 có
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
60 và
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
61. Chúng tôi sẽ kiểm tra ba kịch bản cho
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
62

  1. Nếu
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    30 thì có thể có một giải pháp không sử dụng số nguyên thứ
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    28 trong
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    3. Trong trường hợp này, chúng tôi sẽ thêm một
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    53 mới như thể số nguyên thứ 228 không được bao gồm trong tập hợp con, nhưng số nguyên thứ 1968 là
  2. Nếu
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    37 thì có một giải pháp sử dụng các số nguyên
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    32 còn lại để tạo thành một tập hợp con "trung gian" có tổng bằng
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    39. Trong trường hợp này, chúng tôi sẽ thêm một
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    53 mới giả sử số nguyên thứ
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    28 được bao gồm trong tập hợp con "cuối cùng"
  3. Nếu
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    04 thì chúng ta có giải pháp. Sau đó,
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    05 lưu trữ các chỉ số của số nguyên trong (đã sắp xếp)
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    3 tạo thành một tập hợp con có tổng là
    nums = [-2, 1, -3, 0, 4, 5]
    index = argsort(nums) = [2, 0, 3, 1, 4, 5]
    nums[index] = [-3, -2, 0, 1, 4, 5]
    8
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
3Kết luận 🎉

Tôi hy vọng bạn thích học cách giải bài toán SUBSET-SUM bằng lập trình động. Có khá nhiều tài nguyên trực tuyến giải thích cách xác định xem có tồn tại giải pháp cho một tập hợp cụ thể (

nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
3 ,
nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
8) hay không nhưng thường thì những hướng dẫn này giả định rằng tất cả các số đều dương. Thuật toán được mô tả ở đây cũng hoạt động đối với các số âm. 💡Hơn nữa, hầu như không có hướng dẫn hiện có nào giải thích cách tận dụng bảng DP để quay lại tất cả các giải pháp, đó là động lực chính của bài viết này

Để triển khai cụ thể hơn (C++ và Python, không phải mã giả), vui lòng truy cập GitHub hoặc tải xuống mô-đun pip qua

nums = [-2, 1, -3, 0, 4, 5]
index = argsort(nums) = [2, 0, 3, 1, 4, 5]
nums[index] = [-3, -2, 0, 1, 4, 5]
6