题目
反转链表
链接: 牛客网反转链表
题目描述:给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表头。
数据范围: 0≤n≤1000
要求:空间复杂度 O(1) ,时间复杂度 O(n) 。
如当输入链表{1,2,3}时,
经反转后,原链表变为{3,2,1},所以对应的输出为{3,2,1}。
** 解题思路:**
我们可以让每个节点的next指向前一个的节点,返回最后的节点就可以实现反转链表的需求,因为是题目中给出的链表是单项链表,所以我们需要记录一下修改的当前节点的前一个节点和后一个节点。
代码实现:
public static ListNode reverseList(ListNode head) {
ListNode cur = head;
ListNode prev = null;
ListNode Next = null;
while(null != cur) {
Next = cur.next;//优先记录修改当前节点的下一个节点最后记录可能找不到当前节点
cur.next = prev;//让当前节点的next指向前一个节点
//prev 和 cur同时向后走 Next下一次进入循环在向后走,因为有可能当前节点为最后一个节点Next为null
prev = cur;
cur = Next;
}
return prev;
}
局部反转链表
链接: 局部反转链表
解题思路:
首先新建一个节点,添加到链表头部作为prev节点,通过遍历链表找到开始反转的节点的前一个节点(第m个节点的前一个节点),找到节点后进行链表反转,反转完反转区间的最后一个节点反转完成(第n个节点)。
代码实现:
public ListNode reverseBetween (ListNode head, int m, int n) {
ListNode ret = new ListNode(-1);
ret.next = head;
ListNode prev = ret;
for(int i = 0;i < m - 1;i++) {
prev = prev.next;
}
ListNode cur = prev.next;
ListNode nextNode = null;
for(int i = m;i < n;i++) {
nextNode = cur.next;
cur.next = nextNode.next;
nextNode.next = prev.next;
prev.next = nextNode;
}
return ret.next;
}
合并两个排序链表
链接: 合并两个排序链表
解题思路:
首先创建一个新的节点
ret
方便我们链接链表,将list1.val
与list2.val
的值比较,谁小ret.next
就等于谁,同时将小的节点向后走一步,ret
向后走一步,直到有一方的节点为空了跳出循环,跳出之后进行判断,谁不为空就把他连在ret.next
的后面。
代码实现:
public ListNode Merge(ListNode list1, ListNode list2) {
ListNode ret = new ListNode(-1);
ListNode cur = ret;
while(list1 != null && list2 != null) {
if(list1.val <= list2.val) {
ret.next = list1;
list1 = list1.next;
}else {
ret.next = list2;
list2 = list2.next;
}
ret = ret.next;
}
if(list1 == null) {
ret.next = list2;
}else {
ret.next = list1;
}
return cur.next;
}