遇到一道看似简单,然而实际操作起来却没那么简单的笔试题,现总结如下,虽然实现了功能,但却不知道是否是一个可行的优解,暂时记录一下。
题目描述:
将一个单向链表的第M个位置和第N个位置间的元素顺序倒转,输出倒转后的链表。
例如:
输入:
3 5
11 5 8 22 9 5 0
说明:第一行的两个整数表示链表位置M,N;第二行表示链表元素M,N
输出:
11 5 9 22 8 5 0
说明:输出倒转后的链表
思路:
遍历整个链表,找到需要倒转的部分,记录下它的前面和后面,将倒转部分的元素存储到堆栈中,通过记录好的前后重新连接整个链表。
因为如果交换第一个元素和后面的某个元素,它不存在pre,所以我们自己手动创建一个头结点,放在head前面。
实现:
import java.util.Stack;
class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
public class Main2{
private void Print(ListNode head){
while(head!=null){
System.out.print(head.val+" ");
head=head.next;
}
}
private void solution(ListNode head, int m, int n) {
if(m==n) return;
if(m>n){
int t=m;
m=n;
n=t;
}
Stack<ListNode> s=new Stack<>();
int idx=0;
//考虑交换头指针的情况
ListNode first=new ListNode(-1);
first.next=head;
ListNode p=first;
ListNode pre=first;
ListNode back=null;
while(p!=null){
while(idx<m){
pre=p;
p=p.next;
idx++;
}
while(idx<=n){
s.push(p);
p=p.next;
idx++;
}
back=p;
break;
}
ListNode p2=pre;
while(!s.isEmpty()){
p2.next=s.pop();
p2=p2.next;
}
p2.next=back;
Print(first.next);
return;
}
public static void main(String[] args) {
Main2 m2=new Main2();
ListNode n1 = new ListNode(11);
ListNode n2 = new ListNode(5);
ListNode n3 = new ListNode(8);
ListNode n4 = new ListNode(22);
ListNode n5 = new ListNode(9);
ListNode n6 = new ListNode(5);
ListNode n7 = new ListNode(0);
n1.next = n2;
n2.next = n3;
n3.next = n4;
n4.next = n5;
n5.next = n6;
n6.next = n7;
n7.next = null;
m2.solution(n1,1, 6);
System.out.println();
}
}