Hướng dẫn find 3 largest numbers in an array in javascript - tìm 3 số lớn nhất trong một mảng trong javascript
Edit: Everything below is still valid. However, it was clarified to me in a comment that the original question did not ask for indexes, and many of the answers were responding to the preexisting question. Apologies for any curtness in my original post. Even looking at the original question however, I still disagree with recommending sorting in general for this type of question. I can't believe how many of these answers are worse than the OP's provided solution. Most are more concise, but either:
This may be a little too long for SO, but I feel like this is pertinent information.
I take (3) to mean "I want the method to be more concise / readable", (2) as "indices to be available in the output directly", and (1) to mean "I want the code to be as efficient as possible". Starting from (3) as it'd be most useful to people: Your original algorithm is quite efficient, but you're basically duplicating code in each of the 3 loops; the only difference in each loop really is that the index changes. If you just wanted to cut down on the number of characters, you could re-write your algorithm (with a couple minor caveats1) as:
Beyond the addition of the function, the only thing I really had to add was: This actually ends up being about 4 times slower than your implementation. That slowness is a result of not directly modifying global state (which is faster but harder to maintain) & including that inner function rather than the code duplication. Replacing the inner function with your original duplicated code & leaving every other change the same ends up being 40% faster to execute, because it avoids the creation & calling
of the function entirely; but again is easier to read. It also makes extending Additionally, it should be the same Big-O as your original solution (see my answer to 1), unlike the solutions involving 0; which means it will scale as well as your original solution, while being easier to read & maintain. If you really need the performance, there's very little wrong with your original solution, and I'd even argue your
original solution's better than some of the posted solutions. (For example, from rough testing, increasing the size of the array to ~100 elements makes my solution run about ~3x slower, but makes a solution using 0 run more than 6x slower).1Note: There is one major issue with your algorithm, and that's that 2 is "globally scoped". If you wrote the following, it would run for 3 and then loop forever with 4 & would never finish:
That's because your 5 statements don't reference a "local" version of 2 & will fall back to one that's been defined in a previous scope (or global if it doesn't find one). Your loops always leave 2 set to 8 when they finish, which would change the value in this outer loop. Certain languages & language constructs ( 9 in C# for example) actually won't compile if you've attempted to modify an iterator during a loop. The fix is actually really simple,
& it's just to say const lastMax = max.points[idx - 1] || Number.MAX_VALUE; 0 or const lastMax = max.points[idx - 1] || Number.MAX_VALUE; 1 in your loop declaration & then 2 will only refer to a variable local to the function.There's also the minor problem of your original algorithm ignoring duplicates in the array. If I add another 2 isn't already in const lastMax = max.points[idx - 1] || Number.MAX_VALUE; 7. Depending on the number of duplicates, this could slow the algorithm down (without a rewrite) but assuming const lastMax = max.points[idx - 1] || Number.MAX_VALUE; 8 then it wouldn't be noticeably slower.And while not being a "problem" per-se, it's generally not ideal to have "global state" (i.e. Đề cập ngắn gọn (2): Nếu bản thân các chỉ mục, việc sắp xếp mảng không thực sự có ý nghĩa ngoại trừ trong một số trường hợp rất đặc biệt (xem câu trả lời của tôi cho điểm 1). Sắp xếp là thao tác "tại chỗ" bằng phương thức 0 của JavaScript trực tiếp trên mảng. Điều này có nghĩa là nó sẽ sửa đổi mảng ban đầu trong hầu hết các câu trả lời này; Vì vậy, các chỉ mục ban đầu thực sự bị mất và cũng có những hậu quả khác cho phần còn lại của chương trình. Để sử dụng sắp xếp để có được các giá trị N trên cùng, bạn phải sao chép mảng trước, sắp xếp bản sao, lấy 3 giá trị hàng đầu, sau đó lặp qua mảng gốc ~ 3 lần cố gắng khớp bằng cách sử dụng idx == 0 4 hoặc tương tự (và tương tự (và đối phó với các bản sao).Đây rõ ràng là một sự lãng phí tài nguyên, vì một số câu trả lời này chậm hơn 30 lần so với bản gốc. Bạn có thể thử và tạo một danh sách các "chỉ mục" thay vì các giá trị, sắp xếp chúng dựa trên mảng gốc và điều đó sẽ nhanh hơn một chút. Nhưng trong trường hợp cụ thể này, nơi chúng tôi chỉ muốn "Top 3" (một lần nữa, hãy xem câu trả lời của tôi đến điểm 1) trừ khi tôi bị điên, việc sắp xếp hầu như sẽ luôn chậm hơn. Cuối cùng, nhìn vào (1) thật hữu ích khi áp dụng một khái niệm gọi là "ký hiệu lớn" khi phân tích các thuật toán. Tôi đề nghị googling nó và có một lần đọc, nhưng rộng rãi: chúng tôi muốn xem một thuật toán hiệu quả như thế nào, khi độ dài của đầu vào tăng lên. Ví dụ. Trong ứng dụng của bạn, chúng tôi đã có mảng Ngoài ra, điều quan trọng là phải nói rằng với một mảng trong JS, nếu bạn biết chỉ mục, "tra cứu" thực sự là một hoạt động gần như tức thời Vì vậy, giải pháp ban đầu của bạn là:
Có nghĩa là nó sẽ giống như 0 là lớn của max.points[idx - 1] 3 Điều này có nghĩa là nói rằng, một danh sách ~ 64 mặt hàng, sắp xếp sẽ mất khoảng max.points[idx - 1] 4. Vì vậy, so sánh giải pháp của bạn với các giải pháp liên quan đến 0, trừ khi max.points[idx - 1] 6, không phân loại là thích hợp hơn.Để đưa nó vào quan điểm: Nếu danh sách của bạn có 100 mục, bạn cần phải cố gắng để có được hơn 6 mục "lớn nhất" để sắp xếp để hiệu quả hơn. Nếu đó là 100.000 mặt hàng, bạn cần phải cố gắng để có được hơn 16 mặt hàng "lớn nhất". Trong trường hợp sử dụng này, đặc biệt là khi bạn đã nói rõ ràng "3", hầu như luôn luôn có ý nghĩa hơn để không sắp xếp. Đặc biệt, bởi vì bạn đang cố gắng để có được các chỉ số; Nếu bạn chỉ muốn các giá trị, thì các giải pháp sắp xếp có thể thích hợp hơn chỉ vì chúng đơn giản. Bạn có thể có thể điều chỉnh thuật toán của mình nhiều hơn một chút để tăng tốc độ hơn nữa, nhưng từ thử nghiệm thô: Tôi nghĩ rằng giải pháp của bạn đã là giải pháp nhanh nhất ở đây. Nếu bạn muốn làm cho nó dễ dàng hơn để duy trì / đọc / mở rộng, điều đó chắc chắn là có thể; Nhưng điều đó thực sự không nên đến với chi phí thực sự làm tăng "độ phức tạp thời gian" (tức là làm cho giải pháp tồi tệ hơn |