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] 4. Nếu nums = [-2, 1, -3, 0, 4, 5] 5, có hai tập hợp con đạt được tổng này. nums = [-2, 1, -3, 0, 4, 5] 6 và nums = [-2, 1, -3, 0, 4, 5] 0. Nếu nums = [-2, 1, -3, 0, 4, 5] 1, không có giải pháp nào Show 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] 2 số nguyên trong danh sách nums = [-2, 1, -3, 0, 4, 5] 3 thì tồn tại nums = [-2, 1, -3, 0, 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] 3TLDR;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] 6Logic 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] 3 và nums = [-2, 1, -3, 0, 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] 3 cũng như nums = [-2, 1, -3, 0, 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] 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 nhaunums = [-2, 1, -3, 0, 4, 5] 2Sắ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] 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] 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ầnnums = [-2, 1, -3, 0, 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] 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] 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] 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] 3 thì không có nghiệm nào tồn tạiChú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] 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] 69. Nếu nums = [-2, 1, -3, 0, 4, 5] 20 hoặc nums = [-2, 1, -3, 0, 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 BaptKhi 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] 22. Bảng nums = [-2, 1, -3, 0, 4, 5] 22 sẽ có nums = [-2, 1, -3, 0, 4, 5] 2 hàng (đã cho số nums = [-2, 1, -3, 0, 4, 5] 2) và nums = [-2, 1, -3, 0, 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
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] 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] 22, lưu ý rằng nums = [-2, 1, -3, 0, 4, 5] 26 chỉ có thể là 1 nếu nums = [-2, 1, -3, 0, 4, 5] 27 bằng với nums = [-2, 1, -3, 0, 4, 5] 32nums = [-2, 1, -3, 0, 4, 5] 6Đối với các hàng còn lại, nums = [-2, 1, -3, 0, 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] 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] 3, mà còn (tuyến tính) vào các giá trị của nums = [-2, 1, -3, 0, 4, 5] 3 và nums = [-2, 1, -3, 0, 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] 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] 47 và nums = [-2, 1, -3, 0, 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] 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] 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 🤯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] 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] 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] 53nums = [-2, 1, -3, 0, 4, 5] 3Bâ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] 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] 3 được bao gồm trong tập hợp con, vì vậy, nums = [-2, 1, -3, 0, 4, 5] 56 sẽ là giá trị của nums = [-2, 1, -3, 0, 4, 5] 8 trừ đi nums = [-2, 1, -3, 0, 4, 5] 58nums = [-2, 1, -3, 0, 4, 5] 2Bâ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] 59 có nums = [-2, 1, -3, 0, 4, 5] 60 và nums = [-2, 1, -3, 0, 4, 5] 61. Chúng tôi sẽ kiểm tra ba kịch bản cho nums = [-2, 1, -3, 0, 4, 5] 62
nums = [-2, 1, -3, 0, 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] 3 , nums = [-2, 1, -3, 0, 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] 6 |