给你一个链表的头节点 head
和一个整数 val
,请你删除链表中所有满足 Node.val == val
的节点,并返回 新的头节点 。
示例 1:
输入:head = [1,2,6,3,4,5,6], val = 6 输出:[1,2,3,4,5]
public ListNode removeElements(ListNode head, int val) {
if(head==null)
return null;
ListNode dummy=new ListNode(-1,head);
ListNode pre=dummy,cur=dummy;
while (cur!=null){
if(cur.val==val)
pre.next=cur.next;
else
pre=cur;
cur=cur.next;
}
return dummy.next;
}
给你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
示例 1:
输入:head = [1,2,3,4,5] 输出:[5,4,3,2,1]
方法一
public ListNode removeElements(ListNode head, int val) {
if(head==null)
return null;
ListNode dummy=new ListNode();
ListNode cur=head;
while (cur!=null){
ListNode p=cur.next;
cur.next=dummy.next;
dummy.next=cur;
cur=p;
}
return dummy.next;
}
方法二
public ListNode reverseList(ListNode head) {
if(head==null)
return null;
ListNode pre=null,cur=head;
while (cur!=null){
ListNode t=cur.next;
cur.next=pre;
pre=cur;
cur=t;
}
return pre;
}
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
示例 1:
输入:head = [1,2,3,4] 输出:[2,1,4,3]
思路:想象成一个特殊的二叉树链表,使用后续递归遍历
public ListNode swapPairs(ListNode head) {
if(head==null||head.next==null)
return head;
ListNode next = swapPairs(head.next.next);
ListNode p=head.next;
head.next=next;
p.next=head;
return p;
}
给你一个链表,删除链表的倒数第 n
个结点,并且返回链表的头结点。
示例 1:
输入:head = [1,2,3,4,5], n = 2 输出:[1,2,3,5]
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy=new ListNode(-1,head);
ListNode l=dummy;
ListNode r=l;
for(int i=0;i<=n;i++)
r=r.next;
while (r!=null){
r=r.next;
l=l.next;
}
ListNode temp=l.next;
l.next=temp.next;
return dummy.next;
}
给你一个链表的头节点 head
,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos
不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true
。 否则,返回 false
。
示例 1:
输入:head = [3,2,0,-4], pos = 1 输出:true 解释:链表中有一个环,其尾部连接到第二个节点。
方法一:使用Set
方法二:
public boolean hasCycle(ListNode head) {
if(head==null||head.next==null)
return false;
ListNode fast=head.next;
ListNode slow=head;
while (fast!=slow){
if(fast==null||fast.next==null)
return false;
fast=fast.next.next;
slow=slow.next;
}
return true;
}
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例 1:
输入:l1 = [1,2,4], l2 = [1,3,4] 输出:[1,1,2,3,4,4]
一递归:
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
if(list1==null)
return list2;
if(list2==null)
return list1;
if(list1.val<list2.val){
list1.next=mergeTwoLists(list1.next,list2);
return list1;
}
else {
list2.next=mergeTwoLists(list2.next,list1);
return list2;
}
}
二:
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode prehead = new ListNode(-1);
ListNode prev = prehead;
while (l1 != null && l2 != null) {
if (l1.val <= l2.val) {
prev.next = l1;
l1 = l1.next;
} else {
prev.next = l2;
l2 = l2.next;
}
prev = prev.next;
}
// 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可
prev.next = l1 == null ? l2 : l1;
return prehead.next;
}
给你单链表的头指针 head
和两个整数 left
和 right
,其中 left <= right
。请你反转从位置 left
到位置 right
的链表节点,返回 反转后的链表 。
示例 1:
输入:head = [1,2,3,4,5], left = 2, right = 4 输出:[1,4,3,2,5]
public ListNode reverseBetween(ListNode head, int left, int right) {
ListNode dummy=new ListNode(-1,head);
ListNode pre=dummy;
for(int i=0;i<left-1;i++)
pre=pre.next;
ListNode temp;
ListNode cur=pre.next;
for(int i=0;i<right-left;i++){
temp=cur.next;
cur.next=temp.next;
temp.next=pre.next;
pre.next=temp;
}
return dummy.next;
}
给定一个已排序的链表的头 head
, 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。
示例 1:
输入:head = [1,2,3,3,4,4,5] 输出:[1,2,5]
public ListNode deleteDuplicates(ListNode head) {
if(head==null)
return null;
ListNode dummy=new ListNode(-1,head);
ListNode p=dummy;
while (p.next!=null){
ListNode q=p.next;
while (q.next!=null&&q.next.val==q.val){
q=q.next;
}
if(q==p.next)
p=p.next;
else
p.next=q.next;
}
return dummy.next;
}