定义链表节点
public class ListNode {
public int val;
public ListNode next;
public ListNode(int x){
val = x;
next = null;
}
}
找出单链表中间位置节点
p与q指针同步,q若走不了两步了,p也不要走,因此只判断q是否能走两步即可。
public ListNode FindMidNode(ListNode first){
ListNode p = first, q = first;
while(q!=null && q.next!=null && q.next.next!=null){
q = q.next.next;
p = p.next;
}
return p;
}
找到链表中倒数第k个结点,最后一个算作倒1
找到倒数第k个节点
p,q相差k步,等q走到null,p就是在倒数第k个节点上了。
原题来源:leetcode面试题15
public ListNode FindKReverseNode(ListNode first, int k){
ListNode p = first, q = first;
for(int i = 0; q != null && i < k; q = q.next, i++);
while(q != null){
p = p.next;
q = q.next;
}
return p;
}
删除链表中倒数第k个结点返回链表头,最后一个算作倒1
注意:
删除与查找的不同在于,查找定位到要查找的节点,但是删除却要定位到要删除的节点的前面的那个节点。
那么如果删除的是头结点和第二个结点该如何区分呢。1->2->null 删除倒数第一个和倒数第二个,如何区分。
保持一个p的前面节点pre,初始为null
最后判断pre是否为null,如果为null就是删除头结点,否则就是删除中间的某个节点(此时不会出现pre.next为空的情况,因为不会出现删除的节点是null的情况)
也就是说关键在于区分删除的是头节点还是第二节点即可
原题来源:leetcode19 Remove Nth Node From End of List
public ListNode RemoveKReverseNode(ListNode first, int k){
ListNode pre = null, p = first, q = first;
int i = 0;
for(;q != null && i < k; q = q.next,i++);
if(i < k) return null;//当给出的k不得当,大于链表长度
while(q != null){
q = q.next;
p = p.next;
}
if(pre == null) first= first.next;
else pre.next = pre.next.next;
return first;
}