Làm thế nào để bạn tìm thấy các số trùng lặp trong một mảng nếu nó chứa nhiều số trùng lặp python?
Trước khi xem các giải pháp, hãy nói một chút về vấn đề. Chúng tôi nhận được một mảng của phần tử Ví dụ, với một mảng gồm 5 số nguyên, nó ngụ ý rằng mỗi số nguyên sẽ có giá trị từ 1 đến 4 (bao gồm). Điều này có nghĩa là sẽ tự động có ít nhất một bản sao Ngoại lệ duy nhất là với một mảng có kích thước 1. Đây là trường hợp duy nhất mà chúng ta nên trả về -1 Lực lượng vũ phuGiải pháp vũ phu là thực hiện hai vòng lặp lồng nhau theo cách này for i = 0; i < size(a); i++ { Độ phức tạp thời gian O(n²) và độ phức tạp không gian O(1) Đếm số lần lặpMột giải pháp khác là có cấu trúc dữ liệu để đếm số lần lặp của mỗi số nguyên. Giải pháp này có thể được thực hiện với một mảng hoặc bảng băm Một triển khai trong Java Giá trị của chỉ số Giải pháp này là thời gian O(n) nhưng không gian O(n) vì chúng ta cần một cấu trúc bổ sung Mảng được sắp xếpNếu chúng ta áp dụng kỹ thuật đơn giản hóa, chúng ta có thể thử tìm một giải pháp với một mảng được sắp xếp Trong trường hợp này, chúng ta chỉ cần so sánh từng phần tử với hàng xóm bên phải của nó Trong Java O(1) trong không gian nhưng O(n log(n)) trong thời gian vì chúng tôi cần sắp xếp bộ sưu tập trước Tổng các phần tửMột hướng chúng ta có thể nghĩ đến là tính tổng các phần tử của mảng và so sánh nó với 1 + 2 + … + n Hãy xem một ví dụ Input: [1, 4, 3, 3, 2, 5] Trong ví dụ này, chúng ta có thể tìm nghiệm trong thời gian O(n) và không gian O(1). Tuy nhiên, nó chỉ hoạt động trong trường hợp chúng tôi có một bản sao Một phản ví dụ Input: [1, 2, 3, 2, 3, 4] Hướng này chẳng đi đến đâu. Nhưng đôi khi chúng ta cần thử công cụ để tìm ra giải pháp tối ưu nhất Đánh dấuCó một cái gì đó thú vị để đề cập đến. Cho đến nay, các giải pháp của chúng tôi không thực sự tận dụng thực tế là mỗi số nguyên nằm trong khoảng từ 1 đến Giải pháp là coi mảng cụ thể này là một loại danh sách được liên kết. Bất kỳ chỉ mục nào đang trỏ đến giá trị của chỉ mục đó Chúng tôi lặp lại từng phần tử và đánh dấu chỉ mục tương ứng của nó bằng cách đặt dấu của nó thành dấu trừ. Nếu chúng tôi đã đánh dấu nó là phủ định, điều đó có nghĩa là chỉ mục của nó trùng lặp Hãy xem một ví dụ cụ thể từng bước Input: [2, 3, 3, 1]* Index 0: Trong Java Giải pháp này là O(n) thời gian và O(1) không gian. Tuy nhiên, nó yêu cầu phải thay đổi danh sách đầu vào kỹ thuật chạyCó một giải pháp khác cũng coi mảng đã cho là một loại danh sách được liên kết (một lần nữa, điều này có thể thực hiện được do ràng buộc rằng mỗi số nguyên nằm trong khoảng từ 1 đến Hãy cùng phân tích ví dụ for i = 0; i < size(a); i++ { 1Với biểu diễn này, chúng ta có thể nói một cách đơn giản rằng một bản sao tồn tại khi một chu kỳ tồn tại. Hơn nữa, bản sao là điểm vào của chu trình (trong trường hợp này là phần tử thứ hai) Nếu lấy cảm hứng từ thuật toán tìm chu trình của Floyd, chúng ta có thể rút ra thuật toán sau
Thuật toán đã hoàn thành chưa? . Điểm vào của chu trình này sẽ trùng lặp. Chúng ta phải đặt lại for i = 0; i < size(a); i++ { 2 và di chuyển cả hai con trỏ từng bước cho đến khi chúng bằng nhau trở lại |