从尾到头打印链表_牛客题霸_牛客网 (nowcoder.com)
这个没什么好说的
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
vector<int> nums;
ListNode* h=head;
while (h)
{
nums.push_back(h->val);
h=h->next;
}
//反转
reverse(nums.begin(),nums.end());
return nums;
}
};
这题有两种方法。
1:利用栈的特性,把链表节点一个个入栈,之后再弹出,得到的链表就是反转后的结果。
2:利用双指针,每次取下一个节点,就把置为头节点。
如图:
//栈
private:
stack <ListNode*> Stack;
public:
ListNode* ReverseList(ListNode* head) {
if (head==nullptr) return head;
while (head){
Stack.push(head);
head=head->next;
}
ListNode* newNode = Stack.top();Stack.pop();
ListNode* tmp = newNode;
while (!Stack.empty()){
ListNode* tt = Stack.top();Stack.pop();
newNode->next = tt;
newNode = newNode->next;
}
newNode->next =nullptr; //防止产生环
return tmp;
}
};
//双指针
ListNode* ReverseList(ListNode* head) {
ListNode* newNode=nullptr;
ListNode* tmp;
while (head) {
//保存下一步的位置
tmp = head->next;
//节点换序
head->next = newNode;
newNode = head;
//循环计步
head=tmp;
}
return newNode;
}
};
合并两个排序的链表_牛客题霸_牛客网 (nowcoder.com)
具体题意参考链接
就是说,有两个排好序的链表,把这两个链表重新结合成一个新链表,得到的新链表也得是有序的。
ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
//如果其中的一个链表是空,那么直接返回那个不空的(包括两个链表都是空的情况)
if (pHead1 == nullptr) return pHead2;
if (pHead2 == nullptr) return pHead1;
//新链表
ListNode* node = new ListNode(-1);
ListNode* p1 = pHead1;
ListNode* p2 = pHead2;
//便于后续返回
ListNode* p3 = node;
//比较两个链表的值大小
while (p1 != nullptr && p2 != nullptr) {
if (p1->val < p2->val) {
//新链表的头节点的下一个才存储两个链表比较后的结果
p3->next = p1;
p1 = p1->next;
} else {
p3->next = p2;
p2 = p2->next;
}
p3 = p3->next;
}
//退出循环后
//1)p2比p1短
while (p1) {
p3->next = p1;
p1 = p1->next;
p3 = p3->next;
}
//2)p1比p2短
while (p2) {
p3->next = p2;
p2 = p2->next;
p3 = p3->next;
}
//第二个节点才是两个链表比较后的结果的头节点
return node->next;
}
};
两个链表的第一个公共结点_牛客题霸_牛客网 (nowcoder.com)
这个题有点坑,一开始我以为是两个链表的值有相交,其实是节点一样!!!!
注意一定要比较节点,不是节点的值!!!
方法1:利用哈希表,因为是两个链表的节点一样,那么把其中一个链表按顺序存入哈希表中,只要与另一个链表对比,有重合的值就一定是第一个相交的节点。
class Solution {
public:
unordered_set<ListNode*> set;
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
while (pHead1)
{
set.insert(pHead1); //存节点
pHead1= pHead1->next;
}
while (pHead2){
if (set.count(pHead2)) return pHead2; //找相同的节点
pHead2=pHead2->next;
}
return nullptr;
}
};
方法2:先得出两个链表的长度,然后把最长的链表永远是A,较短的为B链表(便于后续写代码),然后得出B链表的头节点相对于A链表的位置,然后从那个位置A,B开始一直向后找,直到找到重合的节点。
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* headA, ListNode* headB) {
//获取两个链表长度
int sizeA = 0;
int sizeB = 0;
for (ListNode* tmp = headA; tmp != nullptr; tmp = tmp->next) {
sizeA++;
}
for (ListNode* tmp = headB; tmp != nullptr; tmp = tmp->next) {
sizeB++;
}
//让长链表永远是A
int ct = 1, nm;
if (sizeA < sizeB) {
ListNode* tmp = headA;
headA = headB;
headB = tmp;
}
//B链表第一个节点相当与A链表的位置
nm = abs(sizeA - sizeB) + 1;
ListNode* tmp1 = headA;
ListNode* tmp2 = headB;
//找到那个位置
while (tmp1) {
if (ct == nm)
break;
tmp1 = tmp1->next;
ct++;
}
//A链表此时这个位置的节点到末尾与B链表的长度相等
while (tmp1) {
if (tmp1 == tmp2) return tmp1;
tmp1 = tmp1->next;
tmp2 = tmp2->next;
}
return nullptr;
}
};