1.借用的是堆栈,将其进行压入和压出模拟
1 package LeetCode; 2 import java.util.Stack; 3 public class RecordList { 4 5 public static class ListNode 6 { 7 int val; 8 ListNode next; 9 10 ListNode(int x) { 11 val = x; 12 next = null; 13 } 14 15 } 16 ListNode root; 17 18 public RecordList(int array[]) 19 { 20 /*直接建立链表*/ 21 ListNode proot=new ListNode(array[0]); 22 ListNode r=proot; 23 for(int i=1;i<array.length;i++) 24 { 25 26 r.next=new ListNode(array[i]); 27 r=r.next; 28 } 29 30 root=proot; 31 } 32 public void recorderList( ListNode head) 33 { 34 if(head==null) 35 return ; 36 Stack<ListNode> st=new Stack<ListNode>(); 37 38 ListNode firstHead= head.next; 39 while(firstHead!=null) 40 { 41 st.push(firstHead); 42 firstHead=firstHead.next; 43 } 44 45 46 47 ListNode pt=head.next; 48 ListNode newHead=new ListNode(head.val),p=newHead; 49 50 int i=0; 51 52 while(i<st.size()) 53 { 54 p.next=st.peek(); 55 st.pop(); 56 p=p.next; 57 58 p.next=pt; 59 p=p.next; 60 61 pt=pt.next; 62 63 i++; 64 } 65 p.next=null; 66 Print(newHead); 67 } 68 public void Print(ListNode h) 69 { 70 while(h!=null) 71 { 72 System.out.print(h.val+"-->"); 73 h=h.next; 74 75 } 76 } 77 public static void main(String[] args) { 78 79 int [] array={1,2,3,4}; 80 RecordList R=new RecordList(array); 81 R.recorderList(R.root); 82 83 //System.out.print(array.length); 84 85 } 86 }
2.如果不借用堆栈,由题意得recordList最后一个数字肯定是输入原来链表的中间点值,因此使用快慢链表的方式,将原来链表进行分割。
链表的反转和链表的连接;两部分合并
1 package LeetCode; 2 import java.util.Stack; 3 public class RecordList { 4 5 public static class ListNode 6 { 7 int val; 8 ListNode next; 9 10 ListNode(int x) { 11 val = x; 12 next = null; 13 } 14 15 } 16 ListNode root; 17 18 public RecordList(int array[]) 19 { 20 /*直接建立链表*/ 21 ListNode proot=new ListNode(array[0]); 22 ListNode r=proot; 23 for(int i=1;i<array.length;i++) 24 { 25 26 r.next=new ListNode(array[i]); 27 r=r.next; 28 } 29 30 root=proot; 31 } 32 public void recorderList( ListNode head) 33 { 34 if(head==null) 35 return ; 36 Stack<ListNode> st=new Stack<ListNode>(); 37 38 ListNode firstHead= head.next; 39 while(firstHead!=null) 40 { 41 st.push(firstHead); 42 firstHead=firstHead.next; 43 } 44 45 46 47 ListNode pt=head.next; 48 ListNode newHead=new ListNode(head.val),p=newHead; 49 50 int i=0; 51 52 while(i<st.size()) 53 { 54 p.next=st.peek(); 55 st.pop(); 56 p=p.next; 57 58 p.next=pt; 59 p=p.next; 60 61 pt=pt.next; 62 63 i++; 64 } 65 p.next=null; 66 Print(newHead); 67 } 68 public void Print(ListNode h) 69 { 70 while(h!=null) 71 { 72 System.out.print(h.val+"-->"); 73 h=h.next; 74 75 } 76 } 77 public static void main(String[] args) { 78 79 int [] array={1,2,3,4,5}; 80 RecordList R=new RecordList(array); 81 //R.recorderList(R.root); 82 R.recordlist(R.root); 83 //System.out.print(array.length); 84 85 } 86 87 /*只能在本链表上运转,不能使用stack等数据链表 88 * 只能使用快慢指针*/ 89 90 public void recordlist(ListNode head) 91 { 92 if(head==null || head.next==null) 93 return; 94 95 ListNode fast=head,slow=head; 96 97 while(fast.next!=null && fast.next.next!=null) 98 { 99 fast=fast.next.next; 100 slow=slow.next; 101 } 102 /*将链表从中隔离,同时将中点之后的链表进行反转,最后再将其进行连接*/ 103 ListNode f=reverse(slow.next);//此时fast节点已经发生反转 104 105 merge(head,slow,f); 106 } 107 108 public void merge(ListNode head,ListNode end1,ListNode head2) 109 { 110 ListNode pt=head,head1=head; 111 while(head1!=end1) 112 { 113 head1=head1.next; 114 115 pt.next=head2; 116 pt=pt.next;//记着指针要移动 117 118 head2=head2.next; 119 120 121 pt.next=head1; 122 pt=pt.next; 123 } 124 pt.next=null; 125 126 Print(head); 127 } 128 public ListNode reverse(ListNode head) 129 { 130 /*主要讲链表进行反转*/ 131 int i=0; 132 ListNode pre=head, 133 cur=head.next,temp; 134 /*在自身上进行链表反转*/ 135 while(cur!=null) 136 { 137 temp=cur.next; //原链表下一个节点进行保存 138 //将pre连接到当前节点上 139 cur.next=pre; 140 141 //链表向前移动 142 pre=cur; 143 cur=temp; 144 ++i; 145 } 146 //得到会形成循环链表 147 ListNode h=pre; 148 while(i-->0) 149 { 150 h=h.next; 151 } 152 h.next=null; 153 return pre; 154 } 155 }
2.如果不采用指针形式,采用链表自身反转和链表的合并:
1.链表的反转过程中解析:采用链表的循环反转,1-2-3-4 --->2-1-3-4 --->3-2-1-4----->4-3-2-1 pre指针始终指向节点1,将节点1.next移动的链表首部
具体做法:让头结点的。next指向2节点2,让节点1的next指向结点3(保存结点不丢失)最后将结点1连接到结点2后面 2-1-3-4.
同样p1结点总是指向结点1,同样操作,让head。next=结点1的。next
1 public static void reverse(ListNode head) 2 { 3 ListNode p1=head; 4 ListNode p2=head.next; 5 6 while(p2.next!=null) 7 { 8 /*相当于将节点单独的剥离出来*/ 9 ListNode current=p2.next; 10 p2.next=current.next; 11 12 current.next=head.next;/*注意 不能连接 p2,因为p2后面连接的结点不断地变化,最终会让 13 翻转链表树减少*/ 14 p1.next=current; 15 } 16 }
在链表中某一部分进行翻转
1 ListNode p11=head.next,p22=slow.next; 2 //循环链表方式 3 4 while(p11.next!=p22) 5 { 6 ListNode current=p11.next; 7 p11.next=current.next; 8 9 current.next=head.next; 10 head.next=current; 11 Print(head); 12 }
原始序列 1-2-3-4-5-6-7-8
1-->3-->2-->4-->5-->6-->7-->8--> 1-->4-->3-->2-->5-->6-->7-->8-->
即使 1-2-3-4,
1-->4-->3-->2-->
最后进行逐一reorder时候 1-2-3-4-8-7-6-5;将结点8连接到head。next同时 2连接到8.next 1-8-2-3-4-7-6-5 完成一次循环后将指针指向结点2,另外一个指针指向prmid.next 相当于将链表进行
不断地reorder。
1 public static void reorder(ListNode newhead,ListNode premid) 2 { 3 ListNode p1=newhead; 4 ListNode p2=premid.next; 5 6 while(p1!=premid) 7 { 8 //将连接链表进行剥离 9 premid.next=p2.next; 10 p2.next=p1.next; 11 p1.next=p2; 12 13 p1=p2.next; 14 p2=premid.next; 15 } 16 17 }
1