在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。
示例 1:
输入: 4->2->1->3
输出: 1->2->3->4
示例 2:
输入: -1->5->3->4->0
输出: -1->0->3->4->5
测试样例:[4,2,1,3]
我的回答:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
class Solution {
public ListNode sortList(ListNode head) {
List<Integer> list = new ArrayList<>();
ListNode temp = head;
while (temp!= null) {
list.add(temp.val);
temp = temp.next;
}
Collections.sort(list);
temp=head;
for(Integer i:list){
head.val = i;
head = head.next;
}
return temp;
}
}
思路:
将head的值遍历存储到ArrayList中,通过Collections的sort方法进行排序,再将排序后的值再赋值给head,其中需要用一个声明一个ListNode变量,将head的地址赋值给他,返回值也必须是这个变量,而不能直接返回head。
关于返回值的问题
在最开始写这题时,我是直接返回head,测试代码如下
package LeetCode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* ListNode
*/
public class ListNode {
private int val;
private ListNode next;
ListNode(int x) {
val = x;
}
@Override
public String toString() {
if(this==null){
return "";
}
StringBuffer sb=new StringBuffer();
ListNode temp=this.next;
sb.append("{");
sb.append(this.val+",");
while(temp!=null){
sb.append(temp.val+",");
temp=temp.next;
}
sb.setCharAt(sb.length()-1,'}');
return sb.toString();
}
public static ListNode sortList(ListNode head) {
List<Integer> list = new ArrayList<>();
ListNode temp = head;
while (temp!= null) {
list.add(temp.val);
temp = temp.next;
}
Collections.sort(list);
for(Integer i:list){
head.val = i;
head = head.next;
}
return head;
}
public static void main(String[] args) {
ListNode head=new ListNode(4);
head.next=new ListNode(2);
head.next.next=new ListNode(1);
head.next.next.next=new ListNode(3);
System.out.println("返回值head:"+sortList(head));
System.out.println("head:"+head);
}
}
这里我分别打印了head和sortList方法的返回值head,结果如下
为什么会出现这样的情况?
首先我们要了解java的参数传递是值传递,对于基本数据类型的参数,将参数值复制一份传递给方法;对于引用数据类型的参数,将参数引用的地址复制一份传递给方法。即方法都是对传入参数的一个副本进行处理。所以基本数据类型的参数不会被方法改变,但引用数据类型传入的参数的值实际上就是该参数的地址,故该参数内容可能会发生改变。由此来作图分析以上的问题:
在将head传递给sortList方法时,将head的地址复制了一份传递给sortList方法中的head对象,此时他们指向同一个地址。经过for(Integer i: list)操作后,原head指向链表的地址没有改变,但地址中val的值发生了改变;而sortList方法中的head则指的地址发生了改变:
所以如果直接返回方法中的head值将会是是一个空值,而方法外的head值地址并没有改变,值为排序后的链表。所以需要一个新的ListNode变量temp来存储地址8866作为返回值。