14输出倒数第k个结点
该题很多书都有涉及过,且leetcode第19题也是这道题目,其具体的想法是建立两个指针,一个指针先走多少步,然后第二个指针再走,当第一个指针到队尾的时候,即第二个指针为倒数第n个位置。话说本人又做了些并无太大意义的改编,即统计链表长度,然后算出倒数第几个节点,再让第二个指针移动,其实质上和第一种方法区别不大,但代码稍微有些变化。代码如下:
/*
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==NULL)
return NULL;
ListNode* nHead=pListHead;
ListNode* p=pListHead;
int num=0;
while(nHead){
num++;
nHead=nHead->next;
}
if(num<k)
return NULL;
for(int i=0;i<num-k;i++)
p=p->next;
return p;
}
};
15反转链表
看到题目以后写出了如下的代码:
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
if(pHead==NULL)
return pHead;
ListNode* pNew=pHead;
pNew->next=NULL;
while(pHead->next){
ListNode* pNext=pHead->next;
pNext->next=pNew;
pNew=pNext;
pHead=pHead->next;
}
return pNew->next;
}
};
说实话是个愚蠢的想法,其实想法没毛病,新建一个指针指向链表头部,然后运用头插法把后面的元素一个一个插进去,不过事实上写出来有点愚蠢。pNew->=NULL; 直接把链表断开连接。。。我到底在想啥?????正确代码如下:
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
if(pHead==NULL||pHead->next==NULL)
return pHead;
ListNode* pNew=pHead;
ListNode* p=NULL;
ListNode* pNext=pHead->next;
while(pHead){
pNew->next=p;
if(pNext==NULL)
break;
p=pNew;
pNew=pNext;
pNext=pNext->next;
}
return pNew;
}
};
所以到底需要一个pNext来记录下面指针的状态,同时需要保存之前的状态,就能够达到目的了。
16合并两个排序的链表
class Solution {
public:
ListNode* Merge(ListNode* pHead1, ListNode* pHead2){
ListNode* p=NULL;
if(pHead1->val>pHead2->val){
p=pHead2;
pHead2=pHead2->next;
}
else{
ListNode* p=pHead1;
pHead1=pHead1->next;
}
ListNode* answer=p;
while(pHead1&&pHead2){
if(pHead1->val>pHead2->val){
p->next=pHead2;
pHead2=pHead2->next;
p=p->next;
}
else{
p->next=pHead1;
pHead1=pHead1->next;
p=p->next;
}
}
if(!pHead1)
p->next=pHead1;
else
p->next=pHead2;
return answer;
}
};
没看答案之前写出来了个这玩意。。。我也不知道这玩意是啥,反正又长可读性有差,新建了不知道多少个元素,然后发现直接编译不过。。。于是看了答案发现原来可以用递归来着。。。果然递归学得不好啊,想不到啊想不到。正确答案:
class Solution {
public:
ListNode* Merge(ListNode* pHead1, ListNode* pHead2){
if(pHead1==NULL)
return pHead2;
if(pHead2==NULL)
return pHead1;
ListNode* pReturn=NULL;
if(pHead1->val<pHead2->val){
pReturn=pHead1;
pReturn->next=Merge(pHead1->next,pHead2);
}
else{
pReturn=pHead2;
pReturn->next=Merge(pHead1,pHead2->next);
}
return pReturn;
}
};
17树的子结构
class Solution {
public:
bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2){
bool result=false;
if(pRoot1!=NULL&&pRoot2!=NULL){
if(pRoot1->val==pRoot2->val)
result=DoesTree1HaveTree2(pRoot1,pRoot2);
if(!result)
result=HasSubtree(pRoot1->left,pRoot2);
if(!result)
result=HasSubtree(pRoot1,pRoot2->left); //改为result=HasSubtree(pRoot1->right,pRoot2);
}
return result;
}
bool DoesTree1HaveTree2(TreeNode* pRoot1,TreeNode* pRoot2){
if(pRoot2==NULL)
return true;
if(pRoot1==NULL)
return false;
if(pRoot1->val!=pRoot2->val)
return false;
return DoesTree1HaveTree2(pRoot1->left,pRoot2->left)&&DoesTree1HaveTree2(pRoot1->right,pRoot2->right);
}
};
仔细复查了一下,发现第三个判断写错了,应该是result=HasSubtree(pRoot1->right,pRoot2);,这样应该就没毛病了,果然粗心大意是硬伤啊