1.反转链表
这题我使用的是直接将最前面的节点放置到最后,然后然后遍历整个链表的方法。
class Solution {
public:
ListNode* ReverseList(ListNode* head) {
ListNode* newhead = nullptr;/设立一个新的头结点
while (head) {
ListNode* temp = head->next;/存储头结点后面的节点
head->next = newhead;/将存储的反转链表接上去
newhead = head;/存储最前面的节点到newhead
head = temp;/将被夺走了头节点的链表又放回来
}
return newhead;
}
};
2.链表内指定区间反转
遍历到n的位置,然后在n到m之间执行反转链表的操作。
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int m, int n) {
ListNode* a = new ListNode(-1);
a->next = head;
ListNode* b = a;
ListNode* c = head;
for (int i = 1; i < m ; i++) {/遍历到n的位置
b = c;
c = c->next;
}
ListNode* e = nullptr;
ListNode* f = nullptr;
for (int i = m; i < n; i++) {
f = b -> next;
e = c -> next;
b -> next = e;/将第一个节点后面的节点一个一个拿到前面去
c -> next = e->next;
e -> next = f;
}
return (a->next);
}
};
3.链表中的节点每k个一组反转
这题就开始用聪明点的方法了,反转这种操作其实应该马上想到栈,这题就是使用栈来进行操作的。
class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
stack<int> s;
ListNode* temp=head;
ListNode* re=temp;
while(head!=NULL){
for(int i=0;i<k;i++){/每k个输出一次
s.push(head->val);
head=head->next;
if(head==NULL){
if(i<k-1) return re;
else break;
}
}
while(!s.empty()){
temp->val=s.top();
s.pop();
temp=temp->next;
}
}
return re;
}
};
4.合并两个排序的链表
这题之前在滴滴面试真题里做过,使用双指针就可以了。
class Solution {
public:
ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
// write code here
ListNode* temp = new ListNode(0);
ListNode* out = temp;
while (pHead1 != NULL && pHead2 != NULL) {
if (pHead1->val <= pHead2->val) {
temp->next = pHead1;
pHead1 = pHead1->next;
}
else {
temp->next = pHead2;
pHead2 = pHead2->next;
}
temp = temp->next;
}
if (pHead1) temp->next = pHead1;
if (pHead2) temp->next = pHead2;
return out->next;
}
};
5.合并k个已排序的链表
这题我是将两个链表相加写成了函数,然后再调用。
#include <cstddef>
class Solution {
public:
ListNode* add(ListNode* i, ListNode* j) {
ListNode* tmp = new ListNode(0);
ListNode* out = tmp;
while (i != NULL && j != NULL) {
if (i->val <= j->val) {
tmp->next = i;
i = i->next;
} else {
tmp->next = j;
j = j->next;
}
tmp = tmp->next;
}
while (i) {
tmp->next = i;
i = i->next;
tmp = tmp->next;
}
while (j) {
tmp->next = j;
j = j->next;
tmp = tmp->next;
}
return out->next;
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
ListNode* cum = nullptr;
if(lists.size()==0) return 0;
for (int i = 0; i < lists.size(); i++) {
cum = add(cum, lists[i]);
}
return cum;
}
};
6.判断链表中是否有环
这题使用快慢指针即可,只要它们能相等,那么就代表有环。
#include <type_traits>
class Solution {
public:
bool hasCycle(ListNode *head) {
ListNode* fast = head;/快慢指针
ListNode* slow = head;
while(fast!=nullptr&&fast->next!=nullptr){
fast=fast->next->next;
slow=slow->next;
if(fast==slow) return true;
}
return false;
}
};
7.链表中环的入口节点
先快慢指针,然后将快指针变慢从头再来,就可以确定入口了。
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead) {
ListNode* fast = pHead;
ListNode* slow = pHead;
while(fast!=nullptr&&fast->next!=nullptr){
fast=fast->next->next;
slow=slow->next;
if(fast==slow) break;
}
if(fast==nullptr||fast->next==nullptr){
return nullptr;
}
else{
fast=pHead;
while(fast!=slow){
fast=fast->next;
slow=slow->next;
}
return fast;
}
}
};
8.链表中倒数最后k个节点
遍历过去就可以了。
class Solution {
public:
ListNode* FindKthToTail(ListNode* pHead, int k) {
// write code here
int i=0;
ListNode* tmp = pHead;
while(pHead){
pHead=pHead->next;
i++;
}
if(k>i) return nullptr;
for(int j=0;j<i-k;j++){
tmp=tmp->next;
}
return tmp;
}
};
谢谢观看!