206. 反转链表
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
反转链表的思路就是确定一个空结点,让头结点指向空结点,然后确定一个头结点的下一个结点用来依次遍历整个链表。
题目:
剑指 Offer II 024. 反转链表
剑指 Offer 24. 反转链表
206. 反转链表
直接上代码:
/**
* 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 reverseList(ListNode head) {
if(head==null)return head;//这一行必须加,这是防止空指针异常的
ListNode temp=head.next;
ListNode cur=head;
ListNode prev=null;
while(cur!=null){
temp=cur.next;//定义头结点下一个结点,帮助头结点遍历
cur.next=prev;//将头结点指向空结点
prev=cur;//将空节点指向头结点
cur=temp;//将头结点指向下一个节点,这里就是遍历的作用
}
return prev;
}
}
其实上面写的还是有点问题,问题就是temp不需要先赋值,然后只需要初始化,如果只初始化也就不会报空指针异常。
可以看看下面的写法也就是比较正确的写法了:
/**
* 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 reverseList(ListNode head) {
//if(head==null)return head;//这一行必须加,这是防止空指针异常的
//ListNode temp=head.next;
ListNode temp;
ListNode cur=head;
ListNode prev=null;
while(cur!=null){
temp=cur.next;//定义头结点下一个结点,帮助头结点遍历
cur.next=prev;//将头结点指向空结点
prev=cur;//将空节点指向头结点
cur=temp;//将头结点指向下一个节点,这里就是遍历的作用
}
return prev;
}
}
还有一种方法解决反转单链表的作用:递归法
/**
* 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 {
ListNode reverse(ListNode pre,ListNode cur)
{
if(cur==null) return pre;//当cur指向空指针,说明遍历完,直接返回前一个结点就行
ListNode temp=cur.next;//指向头结点的下一个结点
cur.next=pre;//头结点指向空节点
return reverse(cur,temp);//递归反转链表
}
public ListNode reverseList(ListNode head) {
return reverse(null,head);
}
}
这样就把反转链表问题解决了!
难度升级
92. 反转链表 II
给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。
输入:head = [1,2,3,4,5], left = 2, right = 4
输出:[1,4,3,2,5]
代码如下:
/**
* 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 reverseBetween(ListNode head, int left, int right) {
ListNode dummyHead=new ListNode();
dummyHead.next=head;
ListNode s=dummyHead;
ListNode temp;
for(int i=1;i<left;i++)
{
s=s.next;
}
ListNode prev=null;
ListNode cur=s.next;
for(int i=1;i<=(right-left)+1;i++)
{
temp=cur.next;
cur.next=prev;
prev=cur;
cur=temp;
}
s.next.next=cur;
s.next=prev;
return dummyHead.next;
}
}
我的思路是先开始找寻一个前驱临界点,然后反转次数确定之后,剩下就是连接的问题了!