Чтобы понять эту проблему, мы должны провести простую аналогию с примером измерения. Допустим, вам нужно найти место вашей руки, где точно на расстоянии 1 метра от среднего пальца, как бы вы измерили? Вы просто возьмете линейку длиной 1 метр и приложите верхний конец этой линейки к кончику среднего пальца, а нижний конец измерителя будет точно на расстоянии 1 метра от верха вашего среднего пальца. Палец.
То, что мы делаем в этом примере, будет таким же, нам просто нужен фрейм с шириной n элементов, и что нам нужно сделать, это поместить фрейм в конец списка, таким образом, начальный узел фрейма будет ровно n- th элемент в конец списка.
Это наш список, предполагающий, что у нас есть M элементов в списке и наш фрейм шириной N элементов;
HEAD -> EL(1) -> EL(2) -> ... -> EL(M-1) -> EL(M)
<-- Frame -->
Однако нам нужны только границы кадра, поэтому конечная граница кадра будет ровно (N-1) элементов от начальной границы кадра. Так что нужно хранить только эти граничные элементы. Назовем их A и B;
HEAD -> EL(1) -> EL(2) -> ... -> EL(M-1) -> EL(M)
A <- N-Element Wide-> B
Первое, что нам нужно сделать, это найти точку B, которая является концом кадра.
ListNode<T> b = head;
int count = 1;
while(count < n && b != null) {
b = b.next;
count++;
}
Теперь b является n-м элементом массива, а a находится в HEAD. Итак, наш фрейм установлен, мы будем шаг за шагом увеличивать оба граничных узла, пока b не дойдет до конца списка, где a будет от n-го до -последний элемент;
ListNode<T> a = head;
while(b.next != null) {
a = a.next;
b = b.next;
}
return a;
Чтобы собрать все, и с проверками HEAD, N ‹M (где M - размер списка) проверок и прочего, вот метод полного решения;
public ListNode<T> findNthToLast(int n) {
if(head == null) {
return null;
} else {
ListNode<T> b = head;
int count = 1;
while(count < n && b != null) {
b = b.next;
count++;
}
if(count == n && b!=null) {
ListNode<T> a = head;
while(b.next != null) {
a = a.next;
b = b.next;
}
return a;
} else {
System.out.print("N(" + n + ") must be equal or smaller then the size of the list");
return null;
}
}
}
person
Levent Divilioglu
schedule
15.03.2016