第3题:
输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。
解题思路:
不改变原有链表的结构,使用栈实现反向输出。遍历链表,每经过一个节点,把该节点放到栈中。遍历结束后,从栈顶逐个输出节点的值,保存在vector中。
C++
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) :
* val(x), next(NULL) {
* }
* };
*/
class Solution
{
public:
vector<int> printListFromTailToHead(ListNode *head)
{
stack<int> tmp_stack;
vector<int> v1;
ListNode *ptr = head;
while (ptr != nullptr)
{
tmp_stack.push(ptr->val);
ptr = ptr->next;
}
while (!tmp_stack.empty())
{
v1.push_back(tmp_stack.pop());
tmp_stack.pop();
}
return v1;
}
};
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
res=[]
while(listNode != None):
res.append(listNode.val)
listNode=listNode.next
return res[::-1]
第15题:
输入一个链表,反转链表后,输出新链表的表头。
C++
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
if(pHead==nullptr)
return nullptr;
ListNode* p=pHead;
ListNode* q=nullptr;
while(p!=nullptr)//运行3ms
{
ListNode*tmp=p->next;//在逆置前先缓存下一个节点的位置,存在tmp里
p->next=q;//逆置,q为p之前的一个节点
q=p;//让q下移一个节点
p=tmp;
}
/*方法2:运行2ms
while (p != nullptr)
{
ListNode* tmp = q;
q = p;//q向后移,移动到p
p = p->next;//p向后移
q->next = tmp;//q->next 置为null
}
*/
return q;
}
};
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
p=pHead
q=None
while p!=None:
tmp=p.next
p.next=q
q=p
p=tmp
return q
第16题:
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
C++
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
{
ListNode* p1=pHead1;
ListNode* p2=pHead2;
ListNode* head=new ListNode(0);
head->next=nullptr;
ListNode* ptr=head;
while(p1!=nullptr && p2!=nullptr)
{
if(p1->val<p2->val)
{
ptr->next=p1;
p1=p1->next;
}
else
{
ptr->next=p2;
p2=p2->next;
}
ptr=ptr->next;
}
if(p1==nullptr)
ptr->next=p2;
if (p2==nullptr)
ptr->next=p1;
return head->next;
}
};
/*
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)
return pHead2;
if(pHead2==NULL)
return pHead1;
ListNode* head=NULL;
if(pHead1->val <pHead2->val)
{
head=pHead1;
head->next=Merge(pHead1->next,pHead2);
}
if(pHead1->val >pHead2->val)
{
head=pHead2;
head->next=Merge(pHead1,pHead2->next);
}
return head;
}
};
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
head = ListNode(22)
p = head # p用来当做循环操作的指针
# 当两个链表全都不为空,执行循环
while pHead1 and pHead2:
if pHead1.val <= pHead2.val:
p.next = pHead1
# 从pHead1中取出头结点时,头结点变为原头结点的next节点
pHead1 = pHead1.next
elif pHead1.val > pHead2.val:
p.next = pHead2
pHead2 = pHead2.next # 同理
p = p.next # 每次向head3追加一个节点时,指针p偏倚
# 如果pHead1不为None,直接把剩下的pHead1追加到pHead3后
while pHead1:
p.next = pHead1
pHead1 = pHead1.next
p = p.next
# 同理
while pHead2:
p.next = pHead2
pHead2 = pHead2.next
p = p.next
# 返回的结果,去掉head3创建时的无意义首节点
return head.next
方法2:
# -*- 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
ls = []
# 取出两个链表中头节值较小的节点,追加到ls末尾
while pHead1 or pHead2:
# 当pHead1链表所有节点被取光的情况
if pHead1 == None:
ls.append(pHead2)
pHead2 = pHead2.next
# 同理
elif pHead2 == None:
ls.append(pHead1)
pHead1 = pHead1.next
elif pHead1.val <= pHead2.val:
ls.append(pHead1)
pHead1 = pHead1.next
elif pHead1.val > pHead2.val:
ls.append(pHead2)
pHead2 = pHead2.next
# 如果ls为空,说明原两链表都为空,return None
if ls == []:
return None
# 除了列表的最后一个元素,使每个元素的next指向其下一个
for i in range(len(ls)-1):
ls[i].next = ls[i+1]
# 列表最后一个元素的next指向None
ls[len(ls)-1].next = None
# 返回结果
return ls[0]
第14题:
链表中倒数第K个节点
C++
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
//思路:把节点放入vector中,多定义一个计数器n即多增加内存,所以下面的代码可以改进,直接使用
//vector的size()函数求得节点的个数
class Solution {
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
if(pListHead==NULL || k==0)
return NULL;
ListNode* ptr =pListHead;
vector<ListNode*> v1;
unsigned int n=0;
while (ptr != nullptr)
{
v1.push_back(ptr);
n++;
ptr = ptr->next;
}
if(n<k || n==0)
return NULL;
return v1[n-k];
}
};
//改进
class Solution {
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
if(pListHead==NULL || k==0)
return NULL;
vector<ListNode*> data;
while(pListHead != NULL)
{
data.push_back(pListHead);
pListHead=pListHead->next;
}
int len = data.size();
if(len<k || k==0)
return NULL;
return data[len-k];
}
};
//思路2:定义两个指针,中间相隔k-1个距离(节点)
//当第一个节点走到链表最后时,第二个指针即指向倒数第k个节点
/*
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 *p1,*p2;
p1=p2=pListHead;
for(unsigned int i=0;i<k-1;i++)
{
if(p1->next != nullptr)
p1=p1->next;
else
{
return nullptr;
}
}
while(p1->next != nullptr)
{
p1=p1->next;
p2=p2->next;
}
return p2;
}
};
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
node=[]
if (head==None or k==0):
return None
while(head != None):
node.append(head)
head=head.next
length=len(node)
if(length<k or k==0 ):
return None
return node[length-k]
第56题:
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
解题思路: #要删除有序链表中所有的重复节点,而头结点有可能就是重复节点。
#这样的比较好的解决方式就是新建头结点,然后往后遍历,同样的值就全部略过。
C++//错误
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if(pHead==nullptr)
return nullptr;
if(pHead!=nullptr || pHead->next==nullptr)
return pHead;
ListNode *first= new ListNode(-1);
first->next=pHead;
ListNode *p0=first;
ListNode *p1=pHead;
while(p1 != nullptr && p1->next!=nullptr)
{
if(p1->val==p1->next->val)
{
int data=p1->val;
while(p1 !=nullptr && data==p1->val)
{
ListNode*tmp=p1;
p1=p1->next;
delete tmp;
tmp=nullptr;
}
p0->next=p1;
}
else
{
p0=p0->next;
p1=p1->next;
p0->next=p1;
}
}
return first->next;
}
};
python
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def deleteDuplication(self, pHead):
# write code here
#要删除有序链表中所有的重复节点,而头结点有可能就是重复节点。
#这样的比较好的解决方式就是新建头结点,然后往后遍历,同样的值就全部略过。
first=ListNode(-1)#创建一个新的头结点
first.next=pHead
curr=pHead
last=first
while curr and curr.next:
if curr.val != curr.next.val:
curr=curr.next
last=last.next
else :
val=curr.val
while curr and curr.val==val:
curr=curr.next
last.next=curr
return first.next