![a54b174e57cf104df4c5e95caeba419a.png](https://i-blog.csdnimg.cn/blog_migrate/5306af8693a3a9dea9556e64a28ec82d.jpeg)
专题1 链表
1.删除链表中重复的节点
题目描述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
Python
2.两个链表的第一个公共结点
题目描述
输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
![b7e0541cd13570fc78dce129a1a438d1.png](https://i-blog.csdnimg.cn/blog_migrate/865429324dadc045ecb9eefd3ee891af.png)
Python
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def FindFirstCommonNode(self, pHead1, pHead2):
# write code here
def findequal(shortpointer,longpointer,shorthead,longhead):
k = 0
while longpointer:
longpointer = longpointer.next
k += 1
shortpointer = shorthead
longpointer = longhead
for i in range(k):
longpointer = longpointer.next
while shortpointer != longpointer:
shortpointer = shortpointer.next
longpointer = longpointer.next
return shortpointer
pTmp1 = pHead1
pTmp2 = pHead2
while pTmp1 and pTmp2:
if pTmp1 == pTmp2:
return pTmp1
pTmp1 = pTmp1.next
pTmp2 = pTmp2.next
if pTmp1:
return findequal(pTmp2,pTmp1,pHead2,pHead1)
else:
return findequal(pTmp1,pTmp2,pHead1,pHead2)
3.复杂链表的复制
题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
Python
# -*- coding:utf-8 -*-
# class RandomListNode:
# def __init__(self, x):
# self.label = x
# self.next = None
# self.random = None
#import copy
class Solution:
# 返回 RandomListNode
def Clone(self, pHead):
# write code here
#method 1
#ret = copy.deepcopy(pHead)
#return ret
##copy node
if pHead is None:
return None
pTmp = pHead
while pTmp:
node = RandomListNode(pTmp.label)
node.next = pTmp.next
pTmp.next = node
pTmp = node.next
##add ptr 添加指向
pTmp = pHead
while pTmp:
if pTmp.random:
pTmp.next.random = pTmp.random.next
pTmp = pTmp.next.next
##断开连接,取出新的链表
pTmp = pHead
#pNewHead = pHead.next
NewHead = pHead.next
while pTmp.next: #pTmp
#pTmp.next = pTmp.next.next
pTmpNext = pTmp.next
#if pNewHead.next:
#pNewHead.next = pNewHead.next.next
#pNewHead = pNewHead.next
pTmp.next = pTmpNext.next
pTmp = pTmpNext
return NewHead
4.合并两个排序的链表
题目描述
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
Python
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# 返回合并后列表
def Merge(self, pHead1, pHead2):
# write code here
'''
#method1递归解法
if pHead1 is None:
return pHead2
if pHead2 is None:
return pHead1
#res = ListNode(0)
if pHead1.val < pHead2.val:
#res = pHead1
pHead1.next = self.Merge(pHead1.next, pHead2)
return pHead1
else:
#res = pHead2
pHead2.next = self.Merge(pHead1, pHead2.next)
return pHead2
#return res
'''
#method2 非递归,没怎么看懂
tmp = ListNode(0)
pHead = tmp
while pHead1 and pHead2:
if pHead1.val < pHead2.val:
tmp.next = pHead1
pHead1 = pHead1.next
else:
tmp.next = pHead2
pHead2 = pHead2.next
tmp = tmp.next
if not pHead1:
tmp.next = pHead2
if not pHead2:
tmp.next = pHead1
return pHead.next
C++
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
{
if ((pHead1 == NULL)&&(pHead2==NULL))
return NULL;
if(pHead1 == nullptr)
return pHead2;
if(pHead2 == nullptr)
return pHead1;
ListNode* res;
if(pHead1->val < pHead2->val)
{
res = pHead1; //注意递归的使用
pHead1 = pHead1->next;
res->next = Merge(pHead1,pHead2);
}
else
{
res = pHead2;
pHead2 = pHead2->next;
res->next = Merge(pHead1,pHead2);
}
return res;//返回头节点
}
};
5.反转链表
题目描述
输入一个链表,反转链表后,输出新链表的表头。
Python
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# 返回ListNode
def ReverseList(self, pHead):
# write code here
if pHead==None or pHead.next==None:
return pHead
pre = None
cur = pHead
while cur!=None:
tmp = cur.next
cur.next = pre
pre = cur
cur = tmp
return pre
C++
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
ListNode* pNode = pHead;
ListNode* Prev = nullptr;
if(pNode == nullptr || pNode->next==nullptr)//add
return pNode;//add
while(pNode != nullptr)
{
ListNode* pNext = pNode -> next;链断开之前一定要保存断开位置后边的结点
pNode -> next = Prev;//指针反转
Prev = pNode;
pNode = pNext;
//rPhead = pNode;
}
return Prev;
}
};
6.链表中倒数第K个结点
题目描述
输入一个链表,输出该链表中倒数第k个结点。
Python
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def FindKthToTail(self, head, k):
# write code here
#快慢指针
if head is None or k==0:
return None
firstpoint = head
secondpoint = head
for i in range(k):
if firstpoint == None:
return None
firstpoint = firstpoint.next
while firstpoint != None:
firstpoint = firstpoint.next
secondpoint =secondpoint.next
return secondpoint
C++
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k)
{
if(pListHead == nullptr|| k==0)
return nullptr;//有点多余
ListNode *first = pListHead;
ListNode *second = pListHead;
for(unsigned int i=0;i<k;i++)
{
if(first == nullptr)
return nullptr;
first = first->next;
}
//second = pListHead;
while(first != nullptr)
{
first = first->next;
second = second->next;
}
return second;
}
};
7.从尾到头打印链表
题目描述
输入一个链表,按链表从尾到头的顺序返回一个ArrayList
Python
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# 返回从尾部到头部的列表值序列,例如[1,2,3]
def printListFromTailToHead(self, listNode):
# write code here
ret = []
pTmp = listNode
while pTmp:
ret.insert(0,pTmp.val)
pTmp = pTmp.next
return ret
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;
// if(head==NULL)
// return result;
stack<ListNode*> nodes;
ListNode *pNode = head;
while(pNode != nullptr)
{
nodes.push(pNode);
pNode = pNode -> next;
}
while(!nodes.empty())
{
pNode = nodes.top();
result.push_back(pNode->val);
nodes.pop();
}
return result;
}
};
8.从孩子们的游戏
题目描述
每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0...m-1报数....这样下去....直到剩下最后一个小朋友,可以不用表演,并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!^_^)。请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0到n-1)
Python
# -*- coding:utf-8 -*-
class Solution:
def LastRemaining_Solution(self, n, m):
# write code here
#f(n)=(f(n-1)+m)%n; 当n=1,f(1)=0;
if n < 1 or m < 1:
return -1
last = 0
for i in range(2,n+1):
last = (last + m) % i
return last
---------------------------------------------------------------------------------------
C++
class Solution {
public:
int LastRemaining_Solution(int n, int m)
{
if(n < 1 || m < 1)
return -1;
int last = 0;
for(int i=2; i<=n; i++)
{
last = (last + m) % i;
}
return last;
}
};
9.链表中环的入口
题目描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
Python