标签:表操作 节点 get 操作 lang inf count img ISE
思路
存入集合
在集合中进行翻转
遍历操作后的集合 ,构建新的链表
很明显 过程耗时间空间
代码
/**
*6ms 7%
*/
public ListNode reverseKGroup(ListNode head, int k) {
if(head==null) return null;
//存入集合
List<ListNode> nodes=new ArrayList<>();
while(true){
if(head==null){
break;
}
nodes.add(head);
head=head.next;
}
// System.out.println(nodes.toString());
int len=nodes.size();
int mode=len%k;
for(int i=0;i<len-mode;i+=k){
//首尾交换规律
int index=i+(i+k-1);
for(int j=i;j<i+k/2;j++){
ListNode temp=nodes.get(j);
nodes.set(j,nodes.get(index-j));
nodes.set(index-j,temp);
}
}
ListNode head2=new ListNode(-1);
ListNode temp=head2;
nodes.get(len-1).next=null;//若设置末尾为null 例如[1,2] 翻转后[2,1] 但此时1.next.val=2,构成死循环
for(ListNode node:nodes){
temp.next=node;
temp=temp.next;
}
// list(head2.next);
return head2.next;
}
使用 栈 进行链表交换
代码
/**
* 使用栈进行交换
* 3ms 12%
*/
public ListNode reverseKGroup2(ListNode head, int k) {
Stack<ListNode> stack=new Stack<>();
ListNode dummy=new ListNode(-1);
ListNode p=dummy;
while(true){
int count=0;
ListNode tmp=head;
while(tmp!=null&&count<k){
stack.add(tmp);
tmp=tmp.next;
count++;
}
if(count!=k){
p.next=head;
break;
}
while(!stack.isEmpty()){
p.next=stack.pop();
p=p.next;
}
p.next=tmp;
head=tmp;
}
return dummy.next;
}
参考原文王小二:图解k个一组翻转链表
图解如下:
代码
/**
* 0ms
*/
public ListNode reverseKGroup3(ListNode head,int k){
ListNode dummy=new ListNode(-1);
dummy.next=head;
ListNode pre=dummy;
ListNode end=dummy;
while(end.next!=null){
for(int i=0;i<k&&end!=null;i++) end=end.next;
if(end==null) break;
ListNode start=pre.next;
ListNode next=end.next;
end.next=null;
pre.next=reverse(start);
start.next=next;
pre=start;
end=pre;
}
return dummy.next;
}
public ListNode reverse(ListNode head){
ListNode pre=null;
ListNode cur=head;
while(cur!=null){
ListNode next=cur.next;
cur.next=pre;
pre=cur;
cur=next;
}
return pre;
}
? 链表操作(交换)与数组操作 有很大区别 ,数组交换主要是值的交换,而链表是整体。同时需妥善处理next指针,稍不注意易造成节点死循环。 例如[1,2] 翻转后[2,1] 若1.next不设置成null,此时1.next.val=2,构成死循环。
标签:表操作 节点 get 操作 lang inf count img ISE
原文地址:https://www.cnblogs.com/yh-simon/p/12901374.html