文章目录
1.从尾到头打印链表
输入一个链表,按链表从尾到头的顺序返回一个ArrayList。
vector<int> printListFromTailToHead(ListNode* head) {
vector<int> res;
if(!head)
return res;
while(head!=nullptr){
res.push_back(head->val);
head = head->next;
}
reverse(res.begin(),res.end());
return res;
}
注意:此处重点应当是考查栈的使用,不过先输入在反转也可以,时间复杂度一样。
2.链表中倒数第k个结点
输入一个链表,输出该链表中倒数第k个结点。
class Solution {
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
if(pListHead==nullptr || k<=0)
return nullptr;
ListNode* fast=pListHead, *slow=pListHead;
unsigned int i=k;
for(;i>0&&fast;--i)
fast = fast->next;
if(i!=0) return nullptr;
while(fast){
fast = fast->next;
slow = slow->next;
}
return slow;
}
};
3.反转链表
输入一个链表,反转链表后,输出新链表的表头。
ListNode* ReverseList(ListNode* pHead) {
if(pHead==nullptr||pHead->next==nullptr)
return pHead;
ListNode *pre=pHead, *now=pHead->next, *tmp=nullptr;
pre->next = nullptr;
while(now){
tmp = now;
now = now->next;
tmp->next = pre;
pre = tmp;
}
return pre;
}
4. 合并两个排序的链表
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
class Solution {
public:
void merge(ListNode* p1, ListNode* p2,ListNode* head){
ListNode* to=head;
while(p1&&p2){
if(p1->val<=p2->val){
to->next = p1;
to = to->next;
p1 = p1->next;
}else{
to->next = p2;
to = to->next;
p2 = p2->next;
}
}
while(p1){
to->next = p1;
to = to->next;
p1 = p1->next;
}
while(p2){
to->next = p2;
to = to->next;
p2 = p2->next;
}
to->next = nullptr;
}
ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
{
if(!pHead1)
return pHead2;
else if(!pHead2)
return pHead1;
ListNode *p1=pHead1, *p2=pHead2, *head;
if(p1->val<=p2->val){
head = p1;
merge(p1->next,p2,head);
}else{
head = p2;
merge(p1,p2->next,head);
}
return head;
}
};
5.复杂链表的复制
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
/*
struct RandomListNode {
int label;
struct RandomListNode *next, *random;
RandomListNode(int x) :
label(x), next(NULL), random(NULL) {
}
};
*/
class Solution {
public:
RandomListNode* CopyNode(RandomListNode* node){
RandomListNode* head = new RandomListNode(node->label);
head->next = node->next;
return head;
}
RandomListNode* Clone(RandomListNode* pHead){
if(!pHead) return nullptr;
RandomListNode* node = pHead, *clone=nullptr;
while(node){//复制单个节点
node->next = CopyNode(node);
node = node->next->next;
}
node = pHead;
while(node){//复制random节点
if(node->random)
node->next->random = node->random->next;
node = node->next->next;
}
RandomListNode* head = pHead->next;
node=pHead;
node->next = head->next;
node = node->next;
clone = head;
while(node){//分离复合链表
clone->next = node->next;
clone = clone->next;
node->next = clone->next;
node = node->next;
}
return head;
}
};
6. 二叉搜索树与双向链表
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
void ConvertNode(TreeNode* proot,TreeNode** plast){
if(!proot)
return;
ConvertNode(proot->left,plast);
proot->left = *plast;
if((*plast))
(*plast)->right = proot;
*plast = proot;
ConvertNode(proot->right,plast);
}
TreeNode* Convert(TreeNode* pRootOfTree)
{
TreeNode *plastnode = nullptr;
ConvertNode(pRootOfTree,&plastnode);
TreeNode* head = plastnode;
while(head!=nullptr && head->left!=nullptr)
head = head->left;
return head;
}
};
7. 两个链表的第一个公共结点
输入两个链表,找出它们的第一个公共结点。(单链表)
class Solution {
public:
void length(ListNode* pHead1, ListNode* pHead2 ,int *l1, int *l2){
(*l1)=(*l2)=0;
while(pHead1)
{ pHead1 = pHead1->next; ++(*l1);}
while(pHead2)
{ pHead2 = pHead2->next; ++(*l2);}
}
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
if(!pHead1 || !pHead2)
return nullptr;
ListNode *pub, *p1=pHead1,*p2=pHead2;
int l1,l2;
length(p1,p2,&l1,&l2);
int tmp =(l1>l2)?(l1-l2):(l2-l1);
while(tmp--){
if(l1>l2)
p1 = p1->next;
else
p2 = p2->next;
}
while(p1!=p2){
p1 = p1->next;
p2 = p2->next;
}
return p1;
}
};
8.链表中环的入口结点(单链表)
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
class Solution {
public:
bool HasCircle(ListNode* phead,ListNode** meet){
if(phead==nullptr || phead->next==nullptr)
return false;
ListNode *slow=phead->next;
ListNode *fast=slow->next;
while(fast&&slow && fast!=slow){
if(fast->next)
fast = fast->next->next;
else
break;
slow = slow->next;
}
(fast==slow)?((*meet)=fast):((*meet)=nullptr);
return (fast==slow);
}
int NumberofCircle(ListNode* phead){
ListNode *meet, *p;
int num=1;
if(!HasCircle(phead,&meet))
return -1;
p = meet->next;
while(p!=meet){
++num;
p = p->next;
}
return num;
}
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
int nums ;
if((nums=NumberofCircle(pHead))==-1)
return nullptr;
ListNode *front=pHead, *rear=pHead;
while(nums--)
front = front->next;
while(front != rear){
front = front->next;
rear = rear->next;
}
return front;
}
};
9. 删除链表中重复的结点
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if(pHead==nullptr || pHead->next==nullptr)
return pHead;
ListNode* preNode = nullptr;
ListNode* pNode = pHead;
while(pNode!=nullptr){
ListNode* next = pNode->next;
bool needDelete = false;
if(next && next->val==pNode->val)
needDelete = true;
if(!needDelete){
preNode = pNode;
pNode = next;
}else{
int val = pNode->val;
ListNode* delNode = pNode;
while(delNode!=nullptr && delNode->val==val){
next = delNode->next;
delete delNode;
delNode = next;
}
if(preNode==nullptr)
pHead = next;
else
preNode->next = next;
pNode = next;
}
}
return pHead;
}
};
10. 数值的整数次方
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
保证base和exponent不同时为0(要考虑全面)
class Solution {
public:
double myPow(double x, int n) {
if(n<0 && (x==0||x==1))
return x;
double res = 1.0; int tmp=n;
while(n){
if(n&1) res *= x;
x *= x;
n = n/2;//常常不知道的是/是向0取整,而>>则是对负数来说则是向负无穷取整
}
return tmp<0?1/res:res;
}
};