从尾到头打印链表
刷题链接:
https://www.nowcoder.com/practice/d0267f7f55b3412ba93bd35cfa8e8035
题目描述
思路一:
我的第一想法是可以遍历链表,将每个节点的值存入数组中,然后将数组进行反转。
复杂度分析
时间复杂度:O(n)。正向遍历一遍链表。
空间复杂度:O(n)。额外使用一个数组存储链表中的每个节点。
python3
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param listNode ListNode类
# @return int整型一维数组
#
class Solution:
def printListFromTailToHead(self , listNode: ListNode) -> List[int]:
res = []
while listNode:
res.append(listNode.val)
listNode = listNode.next
return res[::-1]
C++
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) :
* val(x), next(NULL) {
* }
* };
*/
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
vector<int> result;
ListNode* current = head;
while (current != nullptr) {
result.push_back(current->val);
current = current->next;
}
reverse(result.begin(), result.end());
return result;
}
};
反转链表
刷题链接:
https://www.nowcoder.com/practice/75e878df47f24fdc9dc3e400ec6058ca
题目描述
思路一:
采用双指针迭代,在遍历链表时,将当前节点的next 指针改为指向前一个节点。由于节点没有引用其前一个节点,因此必须事先存储其前一个节点。在更改引用之前,还需要存储后一个节点。最后返回新的头引用。
复杂度分析
时间复杂度:O(n),正向遍历一遍链表。
空间复杂度:O(1),常数空间复杂度。
python3
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param head ListNode类
# @return ListNode类
#
class Solution:
def ReverseList(self , head: ListNode) -> ListNode:
# write code here
pre , cur = None ,head
while cur:
# 暂存后继节点 cur.next
tmp = cur.next
# 修改 next 引用指向
cur.next = pre
# pre 暂存 cur
pre = cur
# cur 访问下一节点
cur = tmp
return pre
C++
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) : val(x), next(nullptr) {}
* };
*/
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类
* @return ListNode类
*/
ListNode* ReverseList(ListNode* head) {
ListNode *cur = head,*pre=nullptr;
while(cur != nullptr){
// 暂存后继节点 cur.next
ListNode *tmp = cur->next;
// 修改 next 引用指向
cur->next = pre;
// pre 暂存 cur
pre = cur;
// cur 访问下一节点
cur = tmp;
}
return pre;
}
};
合并两个排序的链表
刷题链接:
https://www.nowcoder.com/practice/d8b6b4358f774294a89de2a6ac4d9337
题目描述
思路一:
由于两个链表是递增的,可以使用双指针遍历两个链表,通过pHead1.val与pHead2.val的大小关系确定节点添加顺序,两节点指针交替前进,直至遍历完毕。
复杂度分析
时间复杂度:O(m+n),m,n 分别为两个链表的长度。
空间复杂度:O(1),常数空间复杂度。
python3
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param pHead1 ListNode类
# @param pHead2 ListNode类
# @return ListNode类
#
class Solution:
def Merge(self , pHead1: ListNode, pHead2: ListNode) -> ListNode:
cur = head = ListNode(0)
while pHead1 and pHead2:
if pHead1.val <= pHead2.val:
cur.next, pHead1 = pHead1, pHead1.next
else:
cur.next, pHead2 = pHead2, pHead2.next
cur = cur.next
cur.next = pHead1 if pHead1 else pHead2
return head.next
C++
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) : val(x), next(nullptr) {}
* };
*/
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param pHead1 ListNode类
* @param pHead2 ListNode类
* @return ListNode类
*/
ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
ListNode *cur = new ListNode(0);
ListNode *head = cur;
while(pHead1 != nullptr && pHead2 != nullptr){
if(pHead1->val <= pHead2->val){
cur->next = pHead1;
pHead1 = pHead1->next;
}
else{
cur->next = pHead2;
pHead2 = pHead2->next;
}
cur = cur->next;
}
cur->next = pHead1 ? pHead1 : pHead2;
return head->next;
}
};