1. 删除链表中等于给定值val的所有节点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode Node;
struct ListNode* removeElements(struct ListNode* head, int val) {
if (head == NULL) {
return head;
}
Node* pPre = head;
Node* pCur = head->next;
while (pCur != NULL) {
if (val == pCur->val) {
pPre->next = pCur->next;
pCur = pCur->next;
}
else {
pPre = pCur;
pCur = pCur->next;
}
}
if (val == head->val) {
head = head->next;
}
return head;
}
2.反转一个单链表。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode Node;
struct ListNode* reverseList(struct ListNode* head) {
Node* pCur = head;
Node* pNewHead = NULL;
while (pCur) {
head = pCur->next;
pCur->next = pNewHead;
pNewHead = pCur;
pCur = head;
}
return pNewHead;
}
3.给定一个带有头结点 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode Node;
struct ListNode* middleNode(struct ListNode* head) {
Node* pSlow = head;
Node* pFast = head;
while (pFast&&pFast->next) {
pSlow = pSlow->next;
pFast = pFast->next->next;
}
return pSlow;
}
4.输入一个链表,输出该链表中倒数第k个结点。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
typedef struct ListNode Node;
class Solution {
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
if (pListHead == NULL) {
return NULL;
}
Node* pSlow = pListHead;
Node* pFast = pListHead;
while (k > 0 && pFast != NULL) {
pFast = pFast->next;
k--;
}
if (pFast == pListHead || (k > 0 && pFast == NULL)) {
return NULL;
}
while (pFast != NULL) {
pSlow = pSlow->next;
pFast = pFast->next;
}
return pSlow;
}
};
5.将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode Node;
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {
if (l1 == NULL)
return l2;
if (l2 == NULL)
return l1;
if (l1->val < l2->val) {
l1->next = mergeTwoLists(l1->next, l2);
return l1;
}
else {
l2->next = mergeTwoLists(l1, l2->next);
return l2;
}
}
6. 编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前 。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
class Partition {
public:
ListNode* partition(ListNode* pHead, int x) {
// write code here
if (pHead == NULL) {
return NULL;
}
ListNode* lessList = new ListNode(0);
ListNode* greatList = new ListNode(0);
ListNode* pTail1 = lessList;
ListNode* pTail2 = greatList;
ListNode* pCur = pHead;
while (pCur) {
if (pCur->val < x) {
pTail1->next = pCur;
pTail1 = pTail1->next;
}
else {
pTail2->next = pCur;
pTail2 = pTail2->next;
}
pCur = pCur->next;
}
pTail2->next = NULL;
pTail1->next = greatList->next;
return lessList->next;
}
};
7.在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点, 重复的结点不保留,返回链表头指针。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if (pHead == NULL)
return pHead;
ListNode *pPre = NULL; //指向前面最晚访问过的不重复结点
ListNode *pCur = pHead; //指向当前处理的结点
ListNode *pNext = NULL; //指向当前处理结点后面结点
while (pCur != NULL)
{
//当前结点pCur,(其实是p指向当前结点),与它下一个结点pCur->next的val相同,说明要删掉有这个val的所有结点
if (pCur->next != NULL && pCur->next->val == pCur->val)
{
pNext = pCur->next;
//找到pNext,它指向最后一个与pCur val相同的结点,那pCur 到 pNext (包含) 都是要删除的
while (pNext != NULL && pNext->next != NULL && pNext->next->val == pCur->val)
{
pNext = pNext->next;
}
//如果pCur指向链表中第一个元素,pCur -> ... -> pNext ->... , 要删除pCur到pNext, 将指向链表第一个元素的指针pHead指向pNext->next。
if (pCur == pHead)
{
pHead = pNext->next;
}
else//如果pCur不指向链表中第一个元素,pPre -> pCur ->...->pNext ->... ,要删除pCur到pNext,即pPre->next = pNext->next
{
pPre->next = pNext->next;
}
//当前处理的pCur要向链表尾部移动
pCur = pNext->next;
}
else
{
pPre = pCur;
pCur = pCur->next;
}
}
return pHead;
}
};
8.链表的回文结构
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
class PalindromeList {
public:
bool chkPalindrome(ListNode* A) {
// write code here
if (A == NULL)
return false;
else if (A->next == NULL)
return true;
//快慢指针找出中间节点
ListNode* qFast = A;
ListNode* qSlow = A;
while (qFast != NULL && qFast->next != NULL)
{
qFast = qFast->next->next;
qSlow = qSlow->next;
}
//反转
ListNode* p = qSlow->next;
ListNode* p1 = p->next;
while (p != NULL)
{
p->next = qSlow;
qSlow = p;
p = p1;
p1 = p1->next;
}
while (A != qSlow)
{
if ((A->val) != (qSlow->val))
{
return false;
}
else {
if (A->next == qSlow)
{
return true;
}
A = A->next;
qSlow = qSlow->next;
}
}
return true;
}
};
9.求链表的相交节点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode ListNode;
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
if (NULL == headA || NULL == headB)
return NULL;
//确认两个链表是否相交
ListNode* pTailA = headA;
ListNode* pTailB = headB;
int sizeA = 1;
int sizeB = 1;
//找headA链表中的最后一个节点
while (pTailA->next) {
sizeA++;
pTailA = pTailA->next;
}
//找headB链表中的最后一个节点
while (pTailB->next) {
sizeB++;
pTailB = pTailB->next;
}
if (pTailA != pTailB) {
return NULL;
}
//两个链表已相交
int gap = sizeA - sizeB;
ListNode* pCurA = headA;
ListNode* pCurB = headB;
if (gap > 0) {
while (gap--) {
pCurA = pCurA->next;
}
}
else {
while (gap++) {
pCurB = pCurB->next;
}
}
while (pCurA != pCurB) {
pCurA = pCurA->next;
pCurB = pCurB->next;
}
return pCurA;
}
10.判断链表是否有环
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode Node;
bool hasCycle(struct ListNode *head) {
Node* pFast = head;
Node* pSlow = head;
while (pFast && pFast->next) {
pFast = pFast->next->next;
pSlow = pSlow->next;
if (pFast == pSlow)
return true;
}
return false;
}
11.给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode Node;
struct ListNode *detectCycle(struct ListNode *head) {
Node* pSlow = head;
Node* pFast = head;
while (pFast &&pFast->next) {
pFast = pFast->next->next;
pSlow = pSlow->next;
if (pFast == pSlow) {
break;
}
}
if (NULL == pFast || NULL == pFast->next)
return NULL;
Node* pH = head;
Node* pM = pFast;
while (pH != pM) {
pH = pH->next;
pM = pM->next;
}
return pH;
}
12.给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。
要求返回这个链表的深度拷贝。
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node() {}
Node(int _val, Node* _next, Node* _random) {
val = _val;
next = _next;
random = _random;
}
};
*/
Node* BuyNode(int data) {
Node* pNewNode = (Node*)malloc(sizeof(Node));
if (NULL == pNewNode) {
assert(0);
return NULL;
}
pNewNode->val = data;
pNewNode->next = NULL;
pNewNode->random = NULL;
return pNewNode;
}
class Solution {
public:
Node* copyRandomList(Node* head) {
if (NULL == head)
return NULL;
//在原链表中每个节点后插入值相同的新节点
Node* pCur = head;
while (pCur) {
Node* pNewNode = BuyNode(pCur->val);
pNewNode->next = pCur->next;
pCur->next = pNewNode;
pCur = pNewNode->next;
}
//给新节点的随机指针域赋值
pCur = head;
while (pCur) {
Node* pNewNode = pCur->next;
if (pCur->random)
pNewNode->random = pCur->random->next;
pCur = pNewNode->next;
}
//将新节点从原链表中拆下来
pCur = head;
Node* pNewHead = pCur->next;
while (pCur->next) {
Node* pNewNode = pCur->next;
pCur->next = pNewNode->next;
pCur = pNewNode;
}
return pNewHead;
}
};