链表
- 方法一:双指针法/迭代
首先定义一个cur保存head,再定义一个pre初始化为null。
然后就要开始食物了,首先决定 用 tmp 指针保存cur->next 节点(图里的2),接下来要改变 cur->next 的指向了,将 cur->next 指向 pre
接下来,就是循环走下面的代码逻辑了,继续移动pre和cur指针。
最后,cur指针已经指向了空,循环结束,链表也完成了。这时我们返回pre指针就可以了,pre指针就指向了新的头结点。
class Solution {
public ListNode reverseList(ListNode head) {
ListNode pre=null;
ListNode cur=head;
while(cur!=null){
ListNode tmp=cur.next;
cur.next=pre;
pre=cur;
cur=tmp;
}
return pre;
}
}
- 方法2:递归
class Solution {
public ListNode reverseList(ListNode head) {
return reverse(head,null);
}
public ListNode reverse(ListNode cur,ListNode pre){
if(cur==null){//终止条件
return pre;
}
ListNode tmp = cur.next;
cur.next=pre;
return reverse(tmp,cur);
}
}
- 迭代
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dummy = new ListNode();//创建虚拟头结点
dummy.next=head;//定义头指针
ListNode tmp=dummy;// 定义一个临时结点
while(tmp.next!=null&&tmp.next.next!=null){
ListNode node1=tmp.next;//看第一张图
ListNode node2=tmp.next.next;//看第一张图
tmp.next=node2;//第二张图,tmp指向node2
node1.next=node2.next;//node1指向数字3的位置
node2.next=node1;//node2指向node1,此时数字1和2已经交换
tmp=node1;//tmp指向交换后的node1(现在在数字2的位置),继续下一个循环
}
return dummy.next;
}
}
- 方法一:计算链表长度
- 我的思路:1、创建虚拟头结点 2、计算链表长度index 3、删除下标为index-n的结点
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode();//创建虚拟头结点
dummy.next=head;//定义头指针
ListNode pre=dummy;// 定义一个临时结点
int index=0;
while(head!=null){
index++;
head=head.next;
}
for(int i=0;i<index-n;i++){
pre=pre.next;
}
pre.next=pre.next.next;
return dummy.next;
}
}
- 方法2:双指针
- 如果要删除倒数第n个节点,让fast移动n步,然后让fast和slow同时移动,直到fast指向链表末尾。删掉slow所指向的节点就可以了。妙!
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(0);//创建虚拟头结点
dummy.next=head;//定义头指针
ListNode fast=dummy;// 定义快指针
ListNode slow=dummy;// 定义慢指针
for(int i=0;i<n+1;i++){//n+1是因为只有这样同时移动的时候slow才能指向删除节点的上一个节点,这个要想一下不然容易错
fast=fast.next;
}
while(fast!=null){//看图
fast=fast.next;
slow=slow.next;
}
slow.next=slow.next.next;
return dummy.next;
}
}
- 个人思路
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
int m=length(headA);//定义链表A长度
int n=length(headB);//定义链表B长度
int k=Math.abs(m-n);//链表A与B长度差
ListNode curA=headA;//curA指向链表A的头结点
ListNode curB=headB;//curB指向链表B的头结点
while(k>0){//让curA和curB对齐
if(m<n) curB=curB.next;
else{curA=curA.next;}
k--;
}
while(curA!=null&&curB!=null){
if(curA==curB){//此题关键!交点不是数值相等,而是指针相等!
return curA;
}
curA=curA.next;//不同,同时向后移动curA和curB
curB=curB.next;
}
return null;
}
public int length(ListNode head){//计算链表长度
int length=0;
while(head!=null){
length++;
head=head.next;
}
return length;
}
}
- 双指针
- leetcode.cn/problems/in…
- 思路是指针A遍历完headA再遍历headB,指针B遍历完headB再遍历headA,如果他们有交点就返回首个公共结点,没有交点最后就返回null
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode A = headA, B = headB;
while (A != B) {
if(A==null){
A=headB;
}else{
A=A.next;
}
if(B==null){
B=headA;
}else{
B=B.next;
}
// A = A != null ? A.next : headB;
// B = B != null ? B.next : headA;
}
return A;
}
}