1)进行反转单链表:节点的值不发生改变,只需要进行修改节点的指向
进行测试的时候要给方法传入一个头结点
输入:1,2,3,4,5;
输出:5,4,3,2,1;
1)我们先写两个变量,front=head,current=front.next;我们设想一下只用这两个变量是否可以进行反转单链表的操作呢;
我让current.next=front,再让front=current;这是我们就发现current已经无法走到下一个节点了,因为此时current.next已经被修改了,所以我们可以让curNext来进行保存每一次反转操作的current.next的值(这个操作再循环中的第一条语句)
2)循环条件为current.next!=null;
public Node resverse() {if(head==null){throw new RuntimeException("链表长度为空");}Node front=null;Node current=head;Node currentNext=head.next;while(current!=null){ currentNext=current.next;current.next=front;front=current;current=currentNext;}return front; }
2.只遍历单链表一遍,找出链表的中间节点,如果有两个中间节点,那么返回第二个中间节点
输入:1,2,3,4,5,返回:3
输入:1,2,3,4,5,6,返回:4,如果一个链表有两个中间节点,那么我们返回第二个节点
先求出链表的长度,再走count/2步
class Solution {public ListNode middleNode(ListNode head) {ListNode current=head;int count=0;while(current!=null){current=current.next;count++;}current=head;for(int i=0;i
思路:快指针速度是慢指针速度的2倍,一个到结尾了,那么另一个就是中间位置:
1)进行快慢指针,我们可以定义一个快慢指针,一开始让fast节点和slow节点都指向head,然后我们指向循环,让fast一次走两步,让slow一次走一步;
奇数节点fast走到最后一步的时候fast.next为空
偶树节点fast走到最后一步的时候fast为空
2)最终slow就是中间节点
我们可以自己画图演示一下,链表长度为奇数或者链表长度是偶数的截至条件是不一样的
public ListNode middleNode(ListNode head) {ListNode fast=head;ListNode slow=head;while(fast!=null&&fast.next!=null){fast=fast.next.next;slow=slow.next;}return slow;
public ListNode middleNode(ListNode head) {if(head==null){return null;}ListNode fast=head;ListNode slow=head;while(true){if(fast==null||fast.next==null){return slow;}fast=fast.next.next;slow=slow.next;}}
此时那一个判断条件if(fast==null||fast.next==null)必须写在让指针进行移动的前面,因为此时如果连表中只有一个元素的时候,否则会发生空指针异常
第三题:找出链表中的倒数第K个节点,能不能遍历单链表一遍
要找到倒数第K个,要从前向后走len-k步(至少要遍历两遍,因为首先要知道链表的长度);
1)我们进行定义两个快慢指针,fast为快指针,slow是慢指针,我们先让fast走k-1步
2)然后再让fast和slow同时走;等到fast.next为空的时候(或者说fast走到最后一个节点)
3)并返回slow节点,这时的slow才为倒数第K个节点;
从倒数第三个到倒数第一个 走几步?需要走两步
从倒数第四个到倒数第一个 走几步?需要走三步
从倒数第K个到倒数第一个 走几步?需要走k-1步
2)更简单的方法是先求出链表的长度,让current走len-k步,但是需要进行遍历单链表现要求出但是链表长度
class Solution {public ListNode getKthFromEnd(ListNode head, int k) {if(k<=0||k>size()){ //必须加上,否则下面的循环会出现空指针异常,再循环走k-1步的时候会发生空指针异常return null;}int count=0;ListNode current=head;while(current!=null){count++;current=current.next;}current=head;for(int i=0;i
public Node returnLastK(int index) {if(index<0){throw new UnsupportedOperationException("此时的链表的倒数第K个节点位置不正确");}if(head==null){throw new UnsupportedOperationException("此时链表长度是空");}Node fast=head;Node slow=head;for(int i=0;i
思路:
1)我们首先定义一个虚拟节点是newHead作为要合并在一起的总链表的新节点,注意它是一个虚拟节点,里面的值是任意的
2)我们再合并headA和headB这两个链表的时候,保存两个链表的右节点是没有什么用处的,如果发现headA.data>headB.data,我们就把HeadA指向的这个头结点放到先开辟的链表后面,同时让headA进行向后移动
if(headA.data>headB.data)
{
}else if(HeadA.data
}else{
}
3)再进行合并的过程中,两个链表所走的过程中都不可以是空的,所以循环条件是HeadA!=null&&HeadB!=null
4)在循环出来之后,会出现一种情况,HeadA过长或者HeadB过长,此时我们还要进行特殊处理
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {ListNode HeadA=list1;ListNode HeadB=list2;ListNode newHead=new ListNode(-1);ListNode temp=newHead;while(HeadA!=null&&HeadB!=null){if(HeadA.val
class Solution {public ListNode mergeTwoLists(ListNode list1, ListNode list2) {ListNode head1=list1;ListNode head2=list2;ListNode newHead=new ListNode(-1);ListNode current=newHead;while(head1!=null&&head2!=null){if(head1.val>head2.val){current.next=head2;head2=head2.next;current=current.next;}else{current.next=head1;head1=head1.next;current=current.next;}}while(head1!=null){current.next=head1;head1=head1.next;current=current.next;}while(head2!=null){current.next=head2;head2=head2.next;current=current.next;}current.next=null;return newHead.next;}
}
上一篇:【STA】(2)概念