第一题:反转链表
输入一个链表,反转链表后,输出新链表的表头。
法1,递归,递归的思想(想到栈就可以用递归),不用考虑完了,只考虑最后阶段的就行。
法2,头插法。
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
if(pHead==nullptr or pHead->next==nullptr)
return pHead;
auto ret=pHead,pre=ret->next;
ret->next=nullptr; //ret只有头结点,pre有除头结点剩下的
for(auto tmp=ret;pre!=nullptr;){
tmp=pre->next;
pre->next=ret;
ret=pre; //ret是排好的数
pre=tmp; //pre是待排的数
}
return ret;
}
};
第2题:合并两个排序的链表
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
递归,
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;
else if(pHead2==NULL)
return pHead1;
ListNode *p=new ListNode(0);
if(pHead1->val<pHead2->val)
p=pHead1,p->next=Merge(pHead1->next,pHead2);
else
p=pHead2,p->next=Merge(pHead1,pHead2->next);
return p;
}
};
第三题;树的子结构
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
{
if (pRoot1 == nullptr || pRoot2 == nullptr)
return false;
return isTheSameTree(pRoot1, pRoot2) ||
HasSubtree(pRoot1->left, pRoot2) || HasSubtree(pRoot1->right, pRoot2);
}
bool isTheSameTree(TreeNode* pRoot1, TreeNode* pRoot2)
{
if (pRoot2 == nullptr)
return true;
if (pRoot1 == nullptr && pRoot2 != nullptr)
return false;
return pRoot1->val == pRoot2->val &&
isTheSameTree(pRoot1->left, pRoot2->left) && isTheSameTree(pRoot1->right, pRoot2->right);
}
};
第四题 :二叉树的镜像
递归,很简单
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
void Mirror(TreeNode *pRoot) {
if (pRoot == nullptr)
return ;
TreeNode* p=NULL;
p=pRoot->left;
pRoot->left=pRoot->right;
pRoot->right=p;
Mirror(pRoot->left);
Mirror(pRoot->right);
}
};
第五题:顺时针打印矩阵
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
第六题:包含main函数的栈
定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。
第七条:栈的压入和弹出
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
class Solution {
public:
bool IsPopOrder(vector<int> pushV,vector<int> popV) {
stack<int> cs;
int id=0;
for(int i=0;i<pushV.size();++i){
while(cs.empty()||cs.top()!=popV[i]){
cs.push(pushV[id++]);
if(id>pushV.size()){
return false;
}
}
cs.pop();
}
if(cs.empty())
return true;
else
return false;
}
};
第八题:从上往下打印二叉树(层序遍历)
从上往下打印出二叉树的每个节点,同层节点从左至右打印。
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
vector<int> PrintFromTopToBottom(TreeNode* root) {
queue<TreeNode*> que;
que.push(root);
vector<int> ret;
if(que.empty())
return ret;
while(!que.empty()){
root=que.front();
que.pop();
if(!root)
continue;
ret.push_back(root->val);
que.push(root->left);
que.push(root->right);
}
return ret;
}
};
第九题:二叉搜索树的后续遍历序列
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
class Solution {
public:
int a=0;
bool VerifySquenceOfBST(vector<int> sequence) {
if(sequence.empty()&&a==0)
return false;
a=1;
if(sequence.size()<=2)
return true;
int len=sequence.size();
int mid=sequence[len-1];
vector<int>left;
int i=0;
while (i < len - 1 && sequence[i] <= mid) {
left.push_back(sequence[i]);
i++;
}
vector<int>right;
while(i<len-1){
if(sequence[i]<mid)
return false;
right.push_back(sequence[i]);
i++;
}
return VerifySquenceOfBST(left)&&VerifySquenceOfBST(right);
}
};
第十题:二叉树中的和为某一值的路径
输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)
class Solution {
public:
vector<int> tmp;
vector<vector<int>> buffer;
vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
if(root==NULL) return buffer;
tmp.push_back(root->val);
if(expectNumber-root->val==0&&root->left==NULL&&root->right==NULL){
buffer.push_back(tmp);
}
FindPath(root->left,expectNumber-root->val);
FindPath(root->right,expectNumber-root->val);
if(tmp.size()!=0)
tmp.pop_back();
return buffer;
}
};
第十一题:复杂链表的复制
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
这个有点复杂了。原来是A-B-C第一步先A-A'-B-B'-C-C'第二步复制random,第三部是拆开。
struct RandomListNode {
int label;
struct RandomListNode *next, *random;
RandomListNode(int x) :
label(x), next(NULL), random(NULL) {
}
};
*/
class Solution {
public:
RandomListNode* Clone(RandomListNode* pHead)
{
if(pHead == NULL)
return NULL;
RandomListNode *copynode = pHead;
while(copynode)
{
RandomListNode *node = new RandomListNode(copynode->label);;
node->next = copynode->next;
copynode->next = node;
copynode= node->next;
}
copynode = pHead;//指到head;
while(copynode)
{
if(copynode->random != NULL)
{
copynode->next->random = copynode->random->next;
}
copynode = copynode->next->next;
}
RandomListNode *clone = pHead->next;
RandomListNode *temp = NULL;
copynode = pHead;
while(copynode->next)
{
temp = copynode->next;
copynode->next = temp->next;
copynode = temp;
}
return clone;
}
};
第十二题:二叉搜索树与双向链表
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
中序遍历,关键在于要把他构成一个双向链表。
第十三题:字符串的排列
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。