19.删除链表的倒数第N个结点
题目描述
给你一个链表,删除链表的倒数第 n
个结点,并且返回链表的头结点。
题解
使用虚拟头结点,则对于处理链表的第一个结点和其他结点是一样的处理逻辑。
定义p指针和preNode指针,设置虚拟头结点指向链表
p指针先走n步,然后preNode指针再一起走,直至链表为空,此时preNode指向被删除节点。
p指针指向空(就当已知链表长度为len)p走n步,则还剩下len-n,倒数第n个结点,相当于顺数第len-n个结点。因此当p走完n个结点时,和preNode一起走,当p指针为空时,preNode为删除节点。
删除节点需找到其前驱节点,因此p指针可以走(n+1)步。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode node=new ListNode(0);//虚拟头结点
node.next=head;
ListNode p=node;
ListNode preNode=node;
while(n--!=0&&p.next!=null){
p=p.next;
}
p=p.next; //多往后取一个结点,则preNode少走一个结点,即指向被删除节点的前驱
while(p!=null){
p=p.next;
preNode=preNode.next;
}
preNode.next=preNode.next.next;
return node.next;
}
}
时间复杂度:O(n)
空间复杂度:O(1)
面试题02.07.链表相交
题目描述
给你两个单链表的头节点 headA
和 headB
,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null
。
图示两个链表在节点 c1
开始相交:
题目数据 保证 整个链式结构中不存在环。
注意,函数返回结果后,链表必须 保持其原始结构 。
题解
注意点:交点不是数值相等,而是指针相等
解题思想:因为链表长度不一样,可以先保证两链表末端一样长
- 先获取两链表的长度:循环遍历链表长度
- 求出两者差值,让链表长的先遍历到两者一样长,此时两者链表长度相同,末端齐
- 同时移动A,B两条链表,如果两者相等,直接返回,否则退出循环返回空指针
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode p1=headA;
ListNode p2=headB;
int len1=0,len2=0,len=0;
//遍历A,B两条链表的长度
while(p1!=null){
len1++;
p1=p1.next;
}
while(p2!=null){
len2++;
p2=p2.next;
}
p1=headA;
p2=headB;
//让长的链表遍历到两者相等
if(len1>len2){
len=len1-len2;
while(len--!=0){
p1=p1.next;
}
}else{
len=len2-len1;
while(len--!=0){
p2=p2.next;
}
}
//判断是否有相等交点
while(p1!=null){
if(p1==p2){
return p1;
}
p1=p1.next;
p2=p2.next;
}
return null;
}
}