问题:
easy难度
很简单的问题,把一个链表排序反转,从头到尾排序改成尾到头排序
输出输入案例:
Input: 1->2->3->4->5->NULL
Output: 5->4->3->2->1->NULL
我的代码:
(1)递归
递归的方法处理,毕竟时间复杂度为1,空间换时间看起来很好看,不过递归容易栈溢出,测试数据过大的话,java虚拟机栈或者调用native本地方发栈(Sun HotSpot虚拟机会把两种栈合并)肯定会StackOverflow。
递归的概念就是盒子套盒子,一层嵌套一层,无穷无尽。
class Solution {
private ListNode node = null;
public ListNode reverseList(ListNode head) {
if(head != null) {
reverseHelper(head); // 进行递归处理
head.next = null; // 头部归为尾部,next = null不然就出现链表环
}
return node;
}
public ListNode reverseHelper(ListNode head) {// 这里传入是head,作为本方法节点
if(head.next != null) {
// 1、一口气递归到head节点的next尾null,然后返回下一个节点
ListNode next = reverseHelper(head.next);
// 2、把next节点的next属性指向本head节点
next.next = head;
} else {
// 暂存最后一个节点
node = head;
}
return head;
}
}
(2)循环
可以认为空间复杂度为1,循环的话是时间换空间,一般情况情况不会栈溢出。
我用了栈数据结构,所以pop push peek 这样的算法名词用上了。
class Solution {
public ListNode reverseList(ListNode head) {
if(head == null) return head; // 处理掉null
// 使用了栈数据结构,linkedlist是有栈的算法方法的
LinkedList<ListNode> stack = new LinkedList<ListNode>();
while(head != null) {
stack.push(head); // 全部节点进栈
head = head.next;
}
ListNode first = stack.peek();// 暂存头节点
while(stack.size() != 0) {
ListNode top = stack.pop(); // 将栈头部节点拿出并指向栈顶节点
top.next = stack.peek(); // peek这个是看一看头部节点,不是删除并拿出来
}
return first; // 返回头节点
}
}
其他代码:
当然有个更加短小精悍的代码,我上面两个有使用数据结构或者算法,理解上比较容易,别人更好的代码是逻辑比较复杂不过也很有参考价值,贴一个纯粹指针思想的算法。
class Solution {
public ListNode reverseList(ListNode head) {
ListNode result = null;
ListNode l1 = head;
ListNode temp = null;
while(l1 != null){
// 就是result、temp和l1往后挪,一步一步反转
temp = l1;
l1 = l1.next;
temp.next = result;
result =temp;
}
return result;
}
}