第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