反转链表
思路:给定三个节点,pre表示前一个节点,cur表示当前节点,next表示下一个节点。在反转时,将next节点暂存当前节点的下一个节点,将cur指向前一个节点,就会实现当前节点的反转,接下来将pre后移,最后将cur后移到next即可
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
ListNode *pre = NULL, *cur = pHead, *next = NULL;
while (cur) {
next = cur -> next;
cur -> next = pre;
pre = cur;
cur = next;
}
return pre;
}
};
合并两个排序的链表
思路:不断比较两个链表值的大小即可,每次更小的时候右移,当一方达到最后的位置时,将val值设置为INT_MAX
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
#include <climits>
class Solution {
public:
ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
if (pHead1 == nullptr) return pHead2;
if (pHead2 == nullptr) return pHead1;
ListNode *head = new ListNode(0);
ListNode *pre = head;
while (pHead1 || pHead2) {
int val1 = pHead1 ? pHead1 -> val : INT_MAX;
int val2 = pHead2 ? pHead2 -> val : INT_MAX;
if (val1 <= val2) {
pre -> next = pHead1;
pHead1 = pHead1 -> next;
} else {
pre -> next = pHead2;
pHead2 = pHead2 -> next;
}
pre = pre -> next;
}
return head -> next;
}
};
判断链表是否有环
思路:采用快慢指针的思维,设置一个慢指针一次走一步,一个快指针一次走两步,如果存在环的话,那么两个指针一定会相遇的,返回true,如果不存在环,那么快指针一定会先为空,为空则退出寻找,返回false
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool hasCycle(ListNode *head) {
if (head == nullptr || head -> next == nullptr) return false;
ListNode *slow = head, *fast = head;
while (fast && fast -> next) {
slow = slow -> next;
fast = fast -> next -> next;
if (slow == fast) return true;
}
return false;
}
};
两个链表的第一个公共节点
思路:两个链表的长度不一定相等,但是a+b == b + a,所以我们可以在任意链表达到null后变为另一个链表的头来进行遍历,这样可以保证一定相遇
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
ListNode *p1 = pHead1, *p2 = pHead2;
while (p1 != p2) {
p1 = p1 ? p1 -> next : pHead2;
p2 = p2 ? p2 -> next : pHead1;
}
return p1;
}
};
判断一个链表是否为回文结构
思路:前半段和后半段对称的数据串我们称为回文串,但是链表是单向的,眼下第一时间我们能想到开辟一个数组进行暂存,但其实我们也存在原地做法:①利用快慢指针找到链表的中点,快指针每次前进两格,慢指针前进一格,最后慢指针所处位置即为中点。②将中点后面一段链表进行反转,再依次进行比对,存在不相等的值就返回false。
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
class Solution {
public:
/**
*
* @param head ListNode类 the head
* @return bool布尔型
*/
ListNode* reverse(ListNode *head) {
ListNode *pre = nullptr, *cur = head, *next = nullptr;
while (cur) {
next = cur -> next;
cur -> next = pre;
pre = cur;
cur = next;
}
return pre;
}
bool isPail(ListNode* head) {
// write code here
if (head == nullptr || head -> next == nullptr) return true;
ListNode *slow = head, *fast = head;
while (fast && fast -> next) {
slow = slow -> next;
fast = fast -> next -> next;
}
slow = reverse(slow);
while (slow) {
if (slow -> val != head -> val) return false;
slow = slow -> next;
head = head -> next;
}
return true;
}
};
删除有序链表中重复的元素-I
思路:设定一个指针,从头开始遍历,若有相同的则删除,删除代码为node->next = node -> next -> next
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
class Solution {
public:
/**
*
* @param head ListNode类
* @return ListNode类
*/
ListNode* deleteDuplicates(ListNode* head) {
// write code here
if (head == nullptr) return head;
ListNode *cur = head;
while (cur && cur -> next) {
if (cur -> val == cur -> next -> val) cur -> next = cur -> next -> next;
else cur = cur -> next;
}
return head;
}
};
链表中倒数最后k个结点
思路:最容易想到的方法是遍历整个链表得到长度,在遍历程度减去k的值,得到这个点。这里就不用这个方法了。我们可以采用双指针法,快指针可以先遍历k次,然后快慢指针再一起遍历,得到慢指针就是倒数k个节点
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) : val(x), next(nullptr) {}
* };
*/
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param pHead ListNode类
* @param k int整型
* @return ListNode类
*/
ListNode* FindKthToTail(ListNode* pHead, int k) {
// write code here
if (pHead == nullptr) return nullptr;
ListNode *slow = pHead, *fast = pHead;
for (int i = 0; i < k; i ++ ) {
if (fast) fast = fast -> next;
else return nullptr;
}
while (fast) {
slow = slow -> next;
fast = fast -> next;
}
return slow;
}
};
以上就是牛客面试榜单的简单链表题,思路比较简洁,用于让大家快速过一遍😋😋😋