(本文用于个人笔记的书写,很多地方的使用并不专业,如需学习更加建议移步代码随想录官网代码随想录 (programmercarl.com))
一、两两交换链表节点
由于暑假才做过这个题目,所以影响很深刻。看了卡哥的示意图之后自己一遍就写出了。
easy,直接过掉。
public ListNode swapPairs(ListNode head) {
if(head==null){
return null;
}
if(head.next==null){
return head;
}
ListNode a = new ListNode(0);
ListNode b = a; //设置b用于操作
a.next=head;
while(b.next!=null && b.next.next!=null){
ListNode c = b.next;
b.next=c.next;
c.next=b.next.next;
b.next.next=c;
b=c;
}
return a.next;
}
二、删除链表的第n个节点
--》这道题的算法也是非常容易写的,所以也没有遇到什么问题
看到这道题的第一眼是求出长度,然后再进行遍历。虽然时间复杂度也不高,但是就是显得不是很高级
public ListNode removeNthFromEnd(ListNode head, int n) {
//先写暴力写法
if(head==null){
return null;
}
ListNode A =new ListNode(0);
A.next=head;
ListNode B = A; ListNode C = A;
int count = 0;
while(B.next!=null){
count++;
B=B.next;
}
for(int a=0;a<count-n;a++){
C=C.next;
}
C.next=C.next.next;
return A.next;
}
----而代码录里提供的双指针法,虽然实际上运行时间在这道题里差不不大咯
public ListNode removeNthFromEnd(ListNode head, int n) {
//再写双指针法
if(head==null){
return null;
}
ListNode A =new ListNode(0);
A.next=head;
ListNode B = A; ListNode C = A;
for(int i =0; i<n;i++){
C=C.next;
}
while(C.next!=null){
B=B.next;
C=C.next;
}
B.next=B.next.next;
return A.next;
}
三、链表相交
--这道题乍一看是没有什么思路的除了暴力算法。但是看了图后也就恍然大悟了
原理:因为节点相同不单单代表着的是值相同,更重要的是他的next也是相同的,也就是一旦一个节点相同,他后面所有的节点都相同的,如果第一个链表的节点指向空,那么第二个也已经指向空了。
--》个人对于链表的操作还是比较熟练的,所以bug很少,而且基本能够自己改正
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode xu1 = new ListNode(-1);
ListNode A1 = xu1;
xu1.next=headA; int Acount = 0;
ListNode xu2 = new ListNode(-1);
xu2.next=headB; int Bcount = 0;
ListNode B1 =xu2;
//----------很显然我这边有一个bug,如果是最后一个地方才相同的话会判断有误
while(A1.next!=null){
A1=A1.next;
Acount++;
}
while(B1.next!=null){
B1=B1.next;
Bcount++;
}
if(Acount>=Bcount){
ListNode A2 =xu1;
ListNode B2 =xu2;
int len = Acount - Bcount;
for(int i = 0;i<len; i++){
A2=A2.next;
}
//-------这里直接增加一个判断---究其逻辑是和使用的原因是一样的虚节点***
//-------实际上是形成了一条新的链表
if(A2==B2){
return A2;
}
while(A2.next!=null){
//这里其实有个逻辑点,很显然他这个判断A2.next!=null,就是为了让你在这个循环里先.next再判断
//否则就会出现逻辑缺口,最后一个值会取不到,就好像首元结点一样
System.out.println("在A中沉溺与循环哦");
A2=A2.next;
B2=B2.next;
if(A2==B2){
return A2;
}
}
}else{
ListNode A3 =xu1;
ListNode B3 =xu2;
int len = Bcount - Acount;
for(int i =0;i<len;i++){
B3=B3.next;
}
//-------这里直接增加一个判断---究其逻辑是和使用的原因是一样的虚节点***
//-------实际上是形成了一条新的链表
if(A3==B3){
return A3;
}
while(B3.next!=null){
System.out.println("在B中沉溺与循环哦");
A3=A3.next;
B3=B3.next;
if(A3==B3){
return B3;
}
}
}
return null;
}
ps:但是有个究极无敌大收货:类似于
while(A2.next!=null){
//这里其实有个逻辑点,很显然他这个判断A2.next!=null,就是为了让你在这个循环里
//否则就会出现逻辑缺口,最后一个值会取不到,就好像首元结点一样
所以后面的操作必须是先.next再操作,否则逻辑就会出现问题
四、环形链表
嘎嘎难只能说,完全做不了。只能靠着解析和视频勉强看懂.....
--->别问,问就是做不出来,虽然其中的算法实现其实是很简单的....
public ListNode detectCycle(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while (fast != null && fast.next != null) {
fast=fast.next.next;
slow=slow.next;
if(fast==slow){
ListNode N = head;
while(N!=fast){
N =N.next;
fast=fast.next;
}
return N;
}
}
return null;
}