Tôi đã tìm ra giải pháp cho điều này.
Tôi giả sử mảng được khởi tạo với tất cả 0 (nếu không N cần được điền bằng 0) và M là ma trận kề cho biểu đồ. Tôi cho n là số nút (n = | V |).
j,i = 1;
N = new int[n]
while (j <= n && i <= n) {
if (N[i] == 1) {
i++
} else if (N[j] == 1) {
j++;
} else if (M[i,j] == 1) {
N[i] = 1
i++
} else if (i == j) {
j++
} else {
N[j] = 1
j++
}
}
for (z = 1 to n) {
if (N[z] == 0) {
return z
}
}
return NULL
Tại sao điều này làm việc (không chính thức chứng minh): Bất kỳ nút với bất kỳ cạnh đi từ nó không phải là một bồn rửa phổ quát. Vì vậy, nếu M [i, j] là 1 cho bất kỳ j, tôi không thể là một bồn rửa.
Nếu M [i, j] là 0 cho bất kỳ i nào, thì tôi không có cạnh j, và j không thể là bồn rửa chung.
A 1 tại N [i] chỉ định rằng tôi biết đó không phải là bồn rửa và bất kỳ nút nào mà tôi biết không phải là bồn rửa có thể bị bỏ qua cả i và j. Tôi dừng lại khi một trong hai exeeds n.
Bằng cách này tôi tiếp tục kiểm tra bất kỳ nút nào, mà tôi vẫn không biết không phải là bồn rửa, cho đến khi 1 hoặc 0 bồn rửa có thể vẫn còn.
Do đó, bất kỳ nút nào vẫn là 0 ở cuối vòng lặp phải là bồn rửa và sẽ chỉ có 1 hoặc 0 trong số đó.
Tại sao nó là O (n): Điều này luôn tăng hoặc là i hoặc j. Nó dừng lại khi exeeds n. Như vậy trường hợp xấu nhất cho vòng lặp là 2n. Công việc trong vòng lặp là hằng số. Vòng lặp cuối cùng là trường hợp xấu nhất n. Do đó thuật toán là O (3n) = O (n).
Giải pháp này dựa trên ý tưởng về vấn đề người nổi tiếng, đó là cách xem xét cùng một vấn đề.
Bạn có nghĩa là thời gian O (E) không? Bạn có thể phải kiểm tra (gần như) tất cả các cạnh cho một số trường hợp, và # của các cạnh là lên đến N^2. –
Không, ý tôi là O (| V |) - bạn không cần kiểm tra tất cả các cạnh. – flybywire