Đúng thứ tự chỉ số nhưng ngược thứ tự giá trị
Cặp (i,j) là cặp nghịch đảo nếu **i<j và A[i]>A[j]**. Chỉ số bên trái nhỏ hơn chỉ số bên phải, nhưng giá trị bên trái lớn hơn. Hai phần tử bằng nhau không tạo nghịch đảo vì điều kiện là >, không phải ≥.
Với A=[4,1,4,2], các cặp thỏa điều kiện là:
| (i,j) | (A[i],A[j]) |
|---|---|
| (0,1) | (4,1) |
| (0,3) | (4,2) |
| (2,3) | (4,2) |
Có 3 cặp. Hai cặp cùng mang giá trị (4,2) vẫn khác nhau vì thuộc các chỉ số khác nhau. Cặp (0,2) có hai giá trị bằng 4 nên không tính.
Thêm các cặp kết thúc tại chỉ số k
Hàm xét phần đầu A[0] tới A[k]. Các cặp trong phần đầu chia thành hai nhóm: cặp đã nằm hoàn toàn trong A[0] tới A[k−1], và cặp mới có chỉ số bên phải là k.
```python
def nghich_dao(A, k):
if k <= 0:
return 0
c = 0
for i in range(k):
if A[i] > A[k]:
c += 1
return c + nghich_dao(A, k - 1)
```
Gọi `nghich_dao(A,len(A)-1)`. Ở mỗi bước, k là **chỉ số cuối**, không phải số phần tử. Với ví dụ trên, k=3 thêm hai cặp (0,3),(2,3); k=2 không thêm cặp; k=1 thêm (0,1). Tổng là 2+0+1=3.
Mỗi cặp được tính đúng một lần ở bước k=j. Khi dãy rỗng, k=−1 nên trả 0; dãy một phần tử cũng chưa có cặp i<j.
Đối chiếu bằng hai vòng lặp
Có thể đếm trực tiếp từng cặp i<j:
```python
def nghich_dao_lap(A):
c = 0
for i in range(len(A) - 1):
for j in range(i + 1, len(A)):
if A[i] > A[j]:
c += 1
return c
```
Hai bản phải cùng cho 3 trên [4,1,4,2]. Cả hai chỉ đọc và không sửa A. Nếu dùng hàm sắp xếp chèn đã học trước khi đếm, A bị đổi thành dãy không giảm và số cặp nghịch đảo trở thành 0; khi cần đếm trên dữ liệu gốc phải giữ đúng dữ liệu ấy.
Bài luyện
Dãy [4,1,4,2] có bao nhiêu cặp nghịch đảo?
Ba cặp chỉ số là (0,1),(0,3),(2,3).
Còn thiếu một cặp có giá trị (4,2) ở vị trí khác.
Cặp hai giá trị 4 bằng nhau không được tính.
6 là số cặp chỉ số i<j, nhưng không phải cặp nào cũng nghịch đảo.
Lời giải
4 ở chỉ số 0 lớn hơn 1 ở chỉ số 1 và 2 ở chỉ số 3; 4 ở chỉ số 2 lớn hơn 2 ở chỉ số 3. Không có cặp nào khác thỏa đồng thời i<j và A[i]>A[j], nên có 3 cặp.
Bài luyện
Vì sao hai cặp giá trị (4,2) trong ví dụ đều được tính?
Hai giá trị bằng nhau không thỏa >.
Bài toán đếm cặp phần tử theo vị trí.
Một cặp chỉ số chỉ được đếm một lần.
Cần cả thứ tự chỉ số và phép so sánh lớn hơn.
Lời giải
Phần tử 4 ở chỉ số 0 và phần tử 4 ở chỉ số 2 là hai phần tử khác nhau. Cả hai đứng trước phần tử 2 ở chỉ số 3 và lớn hơn nó, nên tạo hai cặp chỉ số riêng biệt.
Bài luyện
Trong lời gọi nghich_dao(A,3) với A=[4,1,4,2], biến c tại bước k=3 nhận giá trị nào?
Có hai phần tử đứng trước lớn hơn 2.
Không phải mọi phần tử đều tạo cặp mới.
Chỉ có A[0] và A[2] lớn hơn A[3]=2.
3 là tổng cả phần đầu, gồm thêm cặp (0,1).
Lời giải
Vòng lặp xét i=0,1,2. So với A[3]=2, các giá trị 4,1,4 cho hai lần điều kiện đúng, nên c=2. Cặp (0,1) được tính ở lời gọi nhỏ hơn.
Bài luyện
Vì sao nghich_dao([],len([])-1) trả 0 mà không đọc phần tử?
Dãy rỗng không có phần tử chỉ số −1.
Dãy rỗng không có phần tử để tạo cặp.
Không có lệnh đọc A[0] trong cơ sở.
Cơ sở nằm trước mọi thao tác đọc A.
Lời giải
len([])−1=−1 nên hàm gặp nhánh k<=0 và trả 0 ngay. Không có hai chỉ số i<j trong dãy rỗng và không cần đọc phần tử nào.
Đang học