链表刷题总结
此博客链接:https://www.cnblogs.com/ping2yingshi/p/12787252.html
总结一:删除链表
删除链表分为以下几种情况:
1.删除链表中的某个节点,只能待删除的节点。
2.删除链表中的某个节点,给了链表的头节点和待删除的数值。
3.删除链表中重复的节点,只保留一个重复的数字。
4.删除链表中重复的节点,只要是重复的数字,都不保留。
5.删除指定位置的节点。
针对以上删除链表,需要用不同的方法解答(解答是按照链表情况顺序给出:
1.把给定的待删除节点的数值变成待删除节点的next的值,并把待删除的节点指向next的next,即把待删除的节点的next节点复制到待删除节点处,并把待删除的节点的next节点删除。
例如:删除链表中的节点
题目链接:https://leetcode-cn.com/problems/delete-node-in-a-linked-list/
核心代码:
node.val=node.next.val;
node.next=node.next.next;
2.这种情况分两种情况:
1)给定的待删除数字在头节点处。此时只需要返回头结点的next即可,就相当于把头结点删除了。
2)不是在头结点处 。在这种情况下,删除一个节点需要这个节点的头结点,遍历链表时,需要用一个节点的next的值判断是否等于待删除的节点。如果当前节点的next的值等于待删除节点,则把当前节点指向待删除节点的next。
例如:删除链表打的节点
题目链接:https://leetcode-cn.com/problems/shan-chu-lian-biao-de-jie-dian-lcof/
核心代码:
while(head!=null)
{
if(head.val==val)//为了判断第一个数 { return head.next; } if(p.next.val==val)//数在中间或者最后 { p.next=p.next.next; return head; } else p=p.next;
}
3.这种情况只需要判断当前节点值是否和下一个节点的值相等,如果相等,则把当前节点的next指向next的next。
例如:删除链表中的重复元素
题目链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list/
核心代码:
while(p.next!=null) { if(p.next.val==p.val) { p.next=p.next.next; } else p=p.next; }
4.这种情况需要把重复的节点都删除,删除节点,还是需要知道待删除的节点的前一个节点。如果第一个节点就开始重复,那需要把头节点也删除,所以重新建立一个虚拟节点。这里创建两个节点,第一个节点记录每个节点的前一个节点,因为每个节点都肯能重复,在创建一个节点来排除重复节点。
例如:删除链表中的重复元素
题目链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii/
核心代码:
ListNode result=new ListNode(0); result.next=head; ListNode p=result;//记录指针 ListNode q=result.next;//判断指针 while(q!=null) { if(q.next!=null&&q.val==q.next.val) { while(q.val==q.next.val&&q.next!=null) { q=q.next; } p.next=q.next; q=q.next; } else { p=p.next; q=q.next; } }
5.删除给定的链表中的第几个数字,如果是正向删除节点,遍历到删除的节点前一个节点即可,如果删除的节点是倒数第几个节点,先计算整个链表长度L,然后用总长度减去给的倒数的第几个,得到整数的个数,遍历即可。
例如:删除链表中倒数第N个节点
题目链接:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/
int count=0; ListNode p=head; ListNode q=head; while(p!=null) { p=p.next; count++; } int k=count-n; if(k==0) return head.next; for(int i=1;i<k;i++) q=q.next; q.next=q.next.next;
------------恢复内容开始------------
总结一:删除链表
删除链表分为以下几种情况:
1.删除链表中的某个节点,只能待删除的节点。
2.删除链表中的某个节点,给了链表的头节点和待删除的数值。
3.删除链表中重复的节点,只保留一个重复的数字。
4.删除链表中重复的节点,只要是重复的数字,都不保留。
5.删除指定位置的节点。
针对以上删除链表,需要用不同的方法解答(解答是按照链表情况顺序给出):
1.把给定的待删除节点的数值变成待删除节点的next的值,并把待删除的节点指向next的next,即把待删除的节点的next节点复制到待删除节点处,并把待删除的节点的next节点删除。
例如:删除链表中的节点
题目链接:https://leetcode-cn.com/problems/delete-node-in-a-linked-list/
核心代码:
node.val=node.next.val;
node.next=node.next.next;
2.这种情况分两种情况:
1)给定的待删除数字在头节点处。此时只需要返回头结点的next即可,就相当于把头结点删除了。
2)不是在头结点处 。在这种情况下,删除一个节点需要这个节点的头结点,遍历链表时,需要用一个节点的next的值判断是否等于待删除的节点。如果当前节点的next的值等于待删除节点,则把当前节点指向待删除节点的next。
例如:删除链表打的节点
题目链接:https://leetcode-cn.com/problems/shan-chu-lian-biao-de-jie-dian-lcof/
核心代码:
while(head!=null)
{
if(head.val==val)//为了判断第一个数 { return head.next; } if(p.next.val==val)//数在中间或者最后 { p.next=p.next.next; return head; } else p=p.next;
}
3.这种情况只需要判断当前节点值是否和下一个节点的值相等,如果相等,则把当前节点的next指向next的next。
例如:删除链表中的重复元素
题目链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list/
核心代码:
while(p.next!=null) { if(p.next.val==p.val) { p.next=p.next.next; } else p=p.next; }
4.这种情况需要把重复的节点都删除,删除节点,还是需要知道待删除的节点的前一个节点。如果第一个节点就开始重复,那需要把头节点也删除,所以重新建立一个虚拟节点。这里创建两个节点,第一个节点记录每个节点的前一个节点,因为每个节点都肯能重复,在创建一个节点来排除重复节点。
例如:删除链表中的重复元素
题目链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii/
核心代码:
ListNode result=new ListNode(0); result.next=head; ListNode p=result;//记录指针 ListNode q=result.next;//判断指针 while(q!=null) { if(q.next!=null&&q.val==q.next.val) { while(q.val==q.next.val&&q.next!=null) { q=q.next; } p.next=q.next; q=q.next; } else { p=p.next; q=q.next; } }
5.删除给定的链表中的第几个数字,如果是正向删除节点,遍历到删除的节点前一个节点即可,如果删除的节点是倒数第几个节点,先计算整个链表长度L,然后用总长度减去给的倒数的第几个,得到整数的个数,遍历即可。
例如:删除链表中倒数第N个节点
题目链接:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/
int count=0; ListNode p=head; ListNode q=head; while(p!=null) { p=p.next; count++; } int k=count-n; if(k==0) return head.next; for(int i=1;i<k;i++) q=q.next; q.next=q.next.next;
总结二:链表的插入
这里分为两种情况:
1.在链表的尾部插入。
2.在链表的头部插入。
1.在链表的尾部插入时,新建一个头结点newhead,建立一个节点cur指向新的头节点,然后把cur的next指向下一个节点。
核心代码:
ListNode newhead=new ListNode(0); ListNode cur=newhead; while(head!=null) { cur.next=head; cur=cur.next; head=head.next; }
2.在链表的头部插入时,新建一个结点newhead,定义一个临时节点temp,指向给的链表的头节点,然后给的头节点向下移动一个,临时节点指向新建的节点newhead,新建的节点移动到临时节点处。
核心代码:
ListNode newhead=new ListNode(0); while(head!=null) { ListNode temp=head; head=head.next; temp.next==newhead; newhead=temp; }
总结三:链表反转
新建一个头节点,存储反转后的链表,把待反转的链表使用头插发插入到反转后的链表中。
总结四:合并两个链表
合并两个链表时,先创建一个新的节点当成合并后的链表的头,然后遍历给的两个待合并的链表,当那个链表中的值小时,用尾插法插入合并的链表的后面,直到两个待合并的链表都为空。
例如:合并两个有序链表
题目链接:https://leetcode-cn.com/problems/merge-two-sorted-lists/
核心代码:
ListNode head =new ListNode(0); ListNode l3=head; if(l1==null) return l2; if(l2==null) return l1; while(l1!=null && l2!=null){ if(l1.val < l2.val) { l3.next=l1; l1=l1.next; l3=l3.next; } else { l3.next=l2; l2=l2.next; l3=l3.next; } } if(l2==null&l1!=null) l3.next=l1; else l3.next=l2;
总结五:两个数相加,每个数存储在一个链表中,每个节点只能存储一个数字。
先判断相加的两个数字是否是反向存储在链表中的,即各位存在链表的第一个节点中,十位存储在链表的第二个数中,依次类推。如果数字不是反向存储在链表中的,先把链表反转。把每个节点的数字相加,判断两个数相加后是否需要进位,如果需要进位,则把进位加入到下两个数字相加处。
例如:两数相加
题目链接:https://leetcode-cn.com/problems/add-two-numbers/
核心代码:
while(l1!=null||l2!=null) { if(l1!=null&&l2!=null) sumnum=(l1.val+l2.val+count); if(l1==null&&l2!=null) sumnum=(l2.val+count); if(l1!=null&&l2==null) sumnum=(l1.val+count); count=sumnum/10; sumnum=sumnum%10; cur.next=new ListNode(sumnum); cur=cur.next; if(l1!=null) l1=l1.next; if(l2!=null) l2=l2.next; } if(count==1) { cur.next=new ListNode(1); }