翻转链表
方法一:头插法
时间复杂度O(N),空间复杂度O(N)
public ListNode reverseList(ListNode head) {
if(head==null){
return null;
}
ListNode dummyHead=new ListNode(-1);//创建一个新的链表
for(ListNode temp=head;temp!=null;temp=temp.next){//利用头插法插入
ListNode curr=new ListNode(temp.val);
curr.next=dummyHead.next;
dummyHead.next=curr;
//dummyHead.next=new ListNode(temp.val, dummyHead.next);上面三句话的缩写
}
return dummyHead.next;
}
分析:
1.这种方法本质上翻转原链表,只不过是可以输出指定的结果;
2.而且这种方法每次循环是都要创建一个新结点,空间复杂度为O(n);
方法二:
优化空间复杂度(O(1))
public ListNode reverseList(ListNode head) {
ListNode dummyHead=new ListNode(-1);//创建虚拟头结点
dummyHead.next=head;//与链表的头结点相连
if(head==null||head.next==null){//首先判断头结点和头结点的下一个元素是否为空
return head;
}else{
ListNode first=dummyHead.next;
ListNode second=first.next;
while(second!=null){//进行图中迭代
first.next= second.next;
second.next=dummyHead.next;//连接虚拟头结点的下一个是因为虚拟头结点不会改变
dummyHead.next=second;
second=first.next;
}
}
return dummyHead.next;
}
分析:这种方法 虽然逻辑上比第一种方法难,但是降低了时间复杂度 时间复杂度为O(1)