题目描述:
链表:
变换成为:
两种思路:
1、第一种比较容易想到,也比较简单,但是就是复杂度比较高,即使能在牛客网的LeetCode上能通过。就是把所有的元素都存储起来呗,然后新建一个链表,循环取第一个,最后一个,第一个,最后一个直到结束为止,并将这写元素插入到新的链表中,程序如下:
import java.util.LinkedList;
public class Solution {
public void reorderList(ListNode head) {
if(head==null || head.next==null){
return ;
}
//用java提供的数据结果存储所有的链表元素。
LinkedList<ListNode> list=new LinkedList<ListNode>();
while(head!=null){
list.add(head);
head=head.next;
}
//新建一个链表。
ListNode newHead=new ListNode(0);
ListNode cur=newHead;
boolean flag=true;
while(!list.isEmpty()){
if(list.size()==1){
list.getFirst().next=null;
}
if(flag){
cur.next=list.removeFirst();//第一个取出后,后来的也就变成了第一个。
}else{
cur.next=list.removeLast();//同理最后一个取出后,倒数第二个也就变成了最后一个。
}
cur=cur.next;
flag=!flag;//这个的意思是从取第一个然后取最后一个。
}
head=newHead.next;//新建链表的时候带表头了,所以返回表头的next.
}
}
这种方法没有什么技巧,就是暴力去新建链表,没有什么难度。而且耗时耗空间,真正的机试不一定能通过。
2、第二种方法,比较有技巧,刚开始我也想到了,但是我想的比较麻烦,就是将链表从中间分开,然后将前半部分的链表倒过来,也就是都变成尾,尾变成头,然后和后一部分链表开始合并就是下:
链表:1->2->3->4->5->6->7->8->9->0
找到中间位置分开:1->2->3->4->5 6->7->8->9->0
然后把前半部分链表倒过来:5->4->3->2->1
然后和后半部分合并,这个时候注意一个问题哦,新的链表必须采用尾插法新建,因为5和6在新链表的最后面,这个方法逻辑上没什么问题但是我最后么有实现,很尴尬的。(问题的根本在于链表元素的个数是偶数还是奇数,这时候的前半部分的头,在新链表中的位置不好确定,需要条件判断,比较麻烦,但如果后半部分链表倒置就不一样了,肯定是从两个链表的头开始。这里看不懂可以评论问我呀,哈哈哈)
但是这个时候如果,把后半部分链表倒过来是不是比较好呢?
倒过来后:0->9->8->7->6
前半部分为: 1->2->3->4->5
这个时候就不用尾插法新建链表了,是不是很方便,哈哈,程序如下:
public class Solution {
public void reorderList(ListNode head) {
if(head == null || head.next == null || head.next.next == null)
return;
ListNode slow = head;
ListNode fast = head;
//快慢指针找到中间结点
while(fast != null && fast.next != null && fast.next.next != null){
slow = slow.next;
fast = fast.next.next;
}
//断开链表,fast指向后半部分链表,head仍然是头结点,之前前半部分链表
fast = slow;
slow = slow.next;
fast.next = null;
//翻转链表
ListNode lastHead = ReverseNode(slow);
ListNode newHead = head;
head = head.next;
//合并链表
while(head != null && lastHead != null){
newHead.next = lastHead;
lastHead = lastHead.next;
newHead = newHead.next;
newHead.next = head;
head = head.next;
newHead = newHead.next;
}
if(head != null)
newHead.next = head;
if(lastHead != null)
newHead.next = lastHead;
}
private ListNode ReverseNode(ListNode head){
ListNode prev = null;
ListNode curr = head;
while(curr != null && curr.next != null){
ListNode next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
curr.next = prev;
return curr;
}
}
欢迎批评指正,谢谢!