Check if an Array Is Sorted
Otrzymujesz tablicę liczb całkowitych nums. Zwróć true, jeśli jest uporządkowana niemalejąco, co oznacza, że każdy element jest mniejszy lub równy elementowi znajdującemu się po nim, a w przeciwnym razie zwróć false. Równe sąsiednie elementy są dozwolone: [2, 2, 3] jest uznawana za posortowaną. Tablica zawierająca jeden element jest posortowana.
Funkcja
- numsinteger-array
- tablica liczb całkowitych do sprawdzenia
- Zwracaboolean
- true, gdy każdy element jest mniejszy lub równy następnemu, w przeciwnym razie false
Ograniczenia
1 ≤ nums.length ≤ 5000-109 ≤ nums[i] ≤ 109
Przykłady
- Wejście
- nums = [1, 3, 3, 7]
- Wyjście
- true
- Wyjaśnienie
- Każdy krok prowadzi w górę lub utrzymuje ten sam poziom: od 1 do 3, od 3 do 3, od 3 do 7. Powtórzenie 3 jest dozwolone, więc odpowiedź to
true.
- Wejście
- nums = [2, 5, 4, 9]
- Wyjście
- false
- Wyjaśnienie
- Krok z 5 do 4 jest malejący. Wystarczy jeden taki krok, aby tablica przestała być posortowana, mimo że 9 na końcu jest największą wartością, więc odpowiedź to
false.
+16 ukrytych testów przy wysłaniu
Pytanie dodatkowe
Jak sprawdzisz w jednym przejściu, czy tablica może być posortowana w dowolnym kierunku: rosnąco lub malejąco?
Podpowiedzi
Otwieraj je po kolei. Każda zdradza trochę więcej.
Jeśli tablica nie jest posortowana, gdzie możesz to zauważyć? Czy musisz porównywać odległe od siebie elementy?
Wystarczy porównać każdy element z tym, który znajduje się bezpośrednio po nim. Sąsiadujące elementy mogą być równe; tylko krok w dół zaburza kolejność.
Przejdź po sąsiednich parach i zwróć
falseprzy pierwszej parze, w której lewa wartość jest większa od prawej. Jeśli taka para nie istnieje, zwróćtrue.
Rozwiązanie
Tablica jest posortowana dokładnie wtedy, gdy żaden element nie jest większy od elementu znajdującego się bezpośrednio po nim. Nie musisz porównywać elementów, które są daleko od siebie: jeśli każda sąsiednia para jest w odpowiedniej kolejności, cała tablica też jest. Dzięki temu sprawdzenie sprowadza się do jednego przejścia po n-1 parach, które można przerwać przy pierwszym spadku.
Posortuj kopię i porównaj
Intuicja
Posortowana tablica to taka, której sortowanie niczego by nie zmieniło. Zrób więc kopię nums, posortuj ją i sprawdź, czy zgadza się z oryginałem element po elemencie. Jeśli wszystkie elementy są zgodne, nums było już uporządkowane.
Dla [2, 5, 4, 9] posortowana kopia to [2, 4, 5, 9]. Na pozycji 1 w oryginale znajduje się 5, a w kopii 4, więc odpowiedzią jest false. Dla [1, 3, 3, 7] kopia jest identyczna z oryginałem, a odpowiedzią jest true.
To poprawne rozwiązanie, ale robi więcej, niż wymaga zadanie. Sortowanie ma złożoność O(n log n), czyli około 6 × 10^4 porównań dla 5000 liczb, a utworzenie kopii wymaga O(n) pamięci. Ponadto zawsze odczytuje całą tablicę, nawet jeśli już pierwsza para elementów jest nieuporządkowana.
Algorytm
- Skopiuj
nums, aby oryginał pozostał bez zmian. - Posortuj kopię w rosnącej kolejności liczbowej.
- Porównaj kopię z
numspozycja po pozycji. - Zwróć
true, jeśli wszystkie pozycje się zgadzają, w przeciwnym raziefalse.
def isSorted(nums):
# sorted returns a new list, so nums itself is left as it was.
return sorted(nums) == numsPorównaj każdą parę sąsiadów
Intuicja
Nie musisz znać posortowanej wersji, aby stwierdzić, czy tablica jest posortowana. Tablica jest uporządkowana niemalejąco dokładnie wtedy, gdy każdy element jest mniejszy lub równy elementowi znajdującemu się bezpośrednio po nim. Ponieważ relacja ≤ jest przechodnia (a ≤ b i b ≤ c oznaczają a ≤ c), sprawdzenie n-1 sąsiednich par obejmuje każdą parę pozycji.
Przejdź przez i od 1 do n-1 i porównaj nums[i-1] z nums[i]. W przypadku [2, 5, 4, 9] para (2, 5) jest poprawna, a para (5, 4) oznacza spadek, więc od razu zwracasz false, nie sprawdzając 9. Równe sąsiednie elementy są poprawne, ponieważ tylko warunek > oznacza błąd.
Każda para jest porównywana raz, więc złożoność czasowa wynosi O(n), a jedyną dodatkową pamięcią jest indeks pętli, O(1). Porównuj te dwie wartości bezpośrednio, zamiast je odejmować: przy wartościach do 10^9 różnica może przekroczyć zakres 32-bitowej liczby całkowitej.
Algorytm
- Wykonaj pętlę dla
iod 1 don-1. - Jeśli
nums[i-1] > nums[i], zwróćfalse. - Jeśli pętla się zakończy, zwróć
true. Pojedynczy element pomija pętlę i jest posortowany.
def isSorted(nums):
for i in range(1, len(nums)):
# One step down anywhere breaks the order.
if nums[i - 1] > nums[i]:
return False
return True
Pułapki i przypadki brzegowe
Pętla jest krótka, więc błędy kryją się na jej brzegach i w porównaniu.
- Uznawanie równych sąsiadujących elementów za błąd. Sprawdzenie
nums[i-1] >= nums[i]odrzuca[1, 3, 3, 7]. Porządek zaburza tylko ścisły spadek (>). - Odczyt poza końcem tablicy. Pętla od
0don-1, która porównujenums[i]znums[i+1], musi zakończyć się o jeden krok wcześniej, w przeciwnym razie odczytuje element spoza tablicy. Rozpoczęcie odi = 1i porównywanie zi-1pozwala uniknąć tego problemu. - Odejmowanie zamiast porównywania.
nums[i] - nums[i-1] >= 0wygląda tak samo, ale10^9 - (-10^9) = 2 × 10^9nie mieści się w 32-bitowej liczbie typu int i zawija się do liczby ujemnej, przez co[-1000000000, 1000000000]zostaje uznana za nieposortowaną. To samo przepełnienie powoduje błędne działanie komparatora qsort zapisanego jakox - y. - Sortowanie liczb jako tekstu. W JavaScript wywołanie
sort()bez funkcji porównującej umieszcza10przed9, więc sprawdzenie przez sortowanie i porównanie daje błędne odpowiedzi.
Najczęstsze pytania4
Jak sprawdzić, czy tablica jest posortowana?
Porównaj każdy element z następnym. Jeśli którykolwiek element jest większy od swojego sąsiada po prawej, tablica nie jest posortowana i możesz zakończyć; jeśli dojdziesz do końca, nie znajdując takiego elementu, jest posortowana. Zajmuje to O(n) czasu i O(1) dodatkowej przestrzeni.
Dlaczego wystarczy sprawdzić sąsiadów?
Relacja porządku jest przechodnia: jeśli a ≤ b i b ≤ c, to a ≤ c. Zatem jeśli każda sąsiednia para jest uporządkowana, to każda para pozycji również jest uporządkowana. I odwrotnie, każda nieposortowana tablica ma co najmniej jedną sąsiednią parę, w której wartość maleje.
Czy tablica z równymi elementami jest posortowana?
W kolejności nierosnącej, tak: [4, 4, 4] jest posortowana, ponieważ żaden element nie jest większy od następnego. Jeśli zadanie wymaga kolejności ściśle rosnącej, zmień test tak, aby odrzucał również równe sąsiednie elementy.
Czy mogę posortować kopię i porównać ją z oryginałem?
Tak, i daje poprawną odpowiedź, ale wymaga czasu O(n log n) i dodatkowej pamięci O(n) na kopię. Sprawdzanie sąsiadów jest szybsze, nie wymaga kopii i może zwrócić wynik już przy pierwszym kroku w dół, bez odczytywania reszty.
Podobne zadania
Zadania oparte na tych samych pomysłach. Rozwiązanie dwóch lub trzech utrwala schemat.
Python
def isSorted(nums):
# Napisz kod tutajPrzypadek 1
Przypadek 2
Wejście
nums = [1, 3, 3, 7]
Oczekiwane
true