1.把数组排成最小的数

class Solution {
public: static bool compare(const string& s1, const string& s2) {
string t1 = s1 + s2;
string t2 = s2 + s1;
return t1 <= t2? true : false;
} string PrintMinNumber(vector<int> numbers) { string str;
int i, len = numbers.size();
if (len<) return str; string res;
vector<string> vt;
for (i = ;i<len;++i) {
stringstream stream;
stream << numbers[i];
stream >> str;
vt.push_back(str);
} sort(vt.begin(), vt.end(), compare);
for (i = ;i<len;++i)
res += vt[i];
return res;
}
};

这里使用string会比使用char*更加快捷方便。

另外使用sort而不是qsort,主要是sort是qsort的升级,且参数更少,不需要制定每个参数占据的内存空间大小。

2.字符流中第一个不重复的字符

少有的一遍通过的程序,眼泪都快流下来了

class Solution
{
public: Solution():index(){ //初始化位置
for(int i=;i<;++i)
pos[i]=-;
} //Insert one char from stringstream
void Insert(char ch)
{
if(pos[ch]==-)
pos[ch]=index;
else if(pos[ch]>=)
pos[ch]=-; ++index;
} //return the first appearence once char in current stringstream
char FirstAppearingOnce()
{
char res='#';
int minv=1e8,i; //设置字符串max值
for(i=;i<;++i){
if(pos[i]>=&&pos[i]<minv){ //若是当前位置小于min,则对min进行更新
res=(char)i;
minv=pos[i];
}
} return res;
} private:
int index;
int pos[];
};

3.求滑动窗口最大值

还是不能一遍通过,而且思维定式,真的很难找到错误的

class Solution {
public:
vector<int> maxInWindows(const vector<int>& num, unsigned int size)
{
int i,j,k,len=num.size();
vector<int> result;
if(len<size||size==)
return result; int max=num[];
for(i=;i<size;++i){ //先寻找第一个窗口的最大值
if(max<num[i])
max=num[i];
}
result.push_back(max); for(i=;i<=(len-size);++i){
j=i+size-;
if(num[j]<max){
//判断最大值是否移出滑动窗口
if(num[i-]!=max)
result.push_back(max);
else{ //确定最大值被移出滑动窗口,重新确定最大值
max=num[i];
for(k=i;k<=j;++k){
if(num[k]>max)
max=num[k];
}
result.push_back(max);
}
}else{
result.push_back(num[j]);
max=num[j];
}
}
return result;
}
};

4.表示数值的字符串(最耗人心力的程序,没有之一)

有空多做几遍,绝对练耐心

class Solution {
public: bool isdigit(const char& ch){
if(ch<=''&&ch>='')
return true;
else return false;
} void scandigits(char** str){
while(**str!='\0'&&isdigit(**str))
++(*str);
} bool isexpand(char** str){
if(**str!='E'&&**str!='e')
return false; ++(*str);
if(**str=='+'||**str=='-')
++(*str); if(**str=='\0')
return false; scandigits(str);
return (**str=='\0')?true:false;
} bool isNumeric(char* strt)
{
if(NULL==strt)
return false; bool digit=true;
char *str=strt; //排除符号干扰,找到第一个数字
while(str){
if(*str=='+'||*str=='-'){
++str;break;
}else if(isdigit(*str)){
break; //找到第一个数字
}
}
if(*str=='\0') return false; scandigits(&str);
if(*str!='\0'){
//针对小数进行处理
if(*str=='.'){
++str;
scandigits(&str); if(*str=='e'||*str=='E')
digit=isexpand(&str);
}else if(*str=='E'||*str=='e'){
digit=isexpand(&str);
}else{
digit=false;
}
} return digit&&(*str=='\0');
} };

5.字符串的排列

《剑指offer》上针对的是无重复字符串的全排列递归做法。

下面贴的是对重复字符进行处理了的全排列递归做法,为了通过测试集,对字符串进行了排序。

class Solution {
public: vector<string> Permutation(string str) { vector<string> res;
int len=str.length();
if(==len) return res;
else if(==len){
res.push_back(str); return res;
} int left=,right=len-;
Permutation(str,left,right,res);
sort(res.begin(),res.end());
return res;
} //递归实现字符交换
void Permutation(string& str,int left,int right,vector<string>& res){ if(left==right){
res.push_back(str);
}else{
for(int i=left;i<=right;++i){
if(isswap(str,left,i)){
swap(str[i],str[left]);
Permutation(str,left+,right,res);
swap(str[i],str[left]);
}
}
}
} private:
void swap(char& a,char& b){
char t=a;a=b;b=t;
} bool isswap(const string& str,const int& left,const int& right){
for(int i=left;i<right;++i)
if(str[i]==str[right])
return false;
return true;
}
};

后续会添加相应的非递归做法。

另外,此题可以扩展为多个子问题,待后续一一解决。

6.求旋转数组的最小数

没有通过测试集,不过自行调试,觉得程序应该是正确的啊

class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) { int len = rotateArray.size();
if ( == len) return ;
else if ( == len) return rotateArray[]; int left = , right = len - , mid;
while (rotateArray[left] >= rotateArray[right]) { if (right - left == ) {
mid = right;break;
} mid = left + (right - left) / ; //如果下标为left/right/mid指向的三个数字相等
if (rotateArray[left] == rotateArray[right] &&
rotateArray[left] == rotateArray[mid]) {
//顺序查找最小元素
return mininorder(rotateArray, left, right);
} if (rotateArray[mid] >= rotateArray[left]) {
left = mid;
}
else if (rotateArray[mid] <= rotateArray[right]) {
right = mid;
}
} return rotateArray[mid];
} private:
int mininorder(const vector<int>& rotateArray, const int& left, const int& right) {
int min = rotateArray[left];
for (int i = left + ;i <= right;++i) {
if (rotateArray[i]<min)
min = rotateArray[i];
}
return min;
}
};

7.扑克牌顺子

class Solution {
public:
bool IsContinuous( vector<int> numbers ) { int len=numbers.size();
if(len<=) return false; //进行排序
sort(numbers.begin(),numbers.end()); int i=,zeronum=,gap,numgap=;
for(i=;i<len;i++){
if(numbers[i]==)
++zeronum;
else break;
} //从非零的下一个位置开始进行计算
for(i=i+;i<len;++i){
gap=numbers[i]-numbers[i-];
if(==gap)
return false;
else if(==gap)
continue;
else{
numgap+=gap-;
}
} if(numgap<=zeronum)
return true;
else return false;
}
};

8.丑数

此题真的不太好理解,需要重复练习几遍方能理解贯通。

class Solution {
public:
int GetUglyNumber_Solution(int index) { if(==index) return ;
else if(==index) return ; long long *uglynum=new long long[index];
uglynum[]=;
int nextuglyindex=; long long min,*p1=uglynum,*p2=uglynum,*p3=uglynum;
while(nextuglyindex<index){
min=minnum(*p1*,*p2*,*p3*);
uglynum[nextuglyindex]=min; while(*p1*<=uglynum[nextuglyindex])
++p1;
while(*p2*<=uglynum[nextuglyindex])
++p2;
while(*p3*<=uglynum[nextuglyindex])
++p3; ++nextuglyindex;
} int res= (int)uglynum[nextuglyindex-];
delete[] uglynum;
return res;
} private:
long long minnum(const long long& num1,const long long& num2,const long long& num3){
long long min=(num1<num2)?num1:num2;
return (num3<min)?num3:min;
}
};

9.正则表达式匹配

class Solution {
public:
bool match(char* str, char* pattern)
{
if(NULL==str||pattern==NULL)
return false;
else return matchstr(str,pattern);
} private:
bool matchstr(char* str,char* pattern){ if(*str=='\0'&&*pattern=='\0')
return true; if(*str!='\0'&&*pattern=='\0')
return false; if(*(pattern+)=='*'){
if(*pattern==*str||(*pattern=='.'&&*str!='\0'))
return matchstr(str+,pattern+)
|| matchstr(str+,pattern)
|| matchstr(str,pattern+);
else return matchstr(str,pattern+);
} if(*str==*pattern||(*pattern=='.'&&*str!='\0'))
return matchstr(str+,pattern+); return false;
}
};

return使用||返回几个可能结果,状态之间的变化,简直不能再赞了

10.树的子结构

/*
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* root1, TreeNode* root2)
{
bool res=false; if(root1!=NULL&&root2!=NULL){
if(root1->val==root2->val){
res=judgetree(root1,root2);
}
if(!res)
res=HasSubtree(root1->left,root2);
if(!res)
res=HasSubtree(root1->right,root2);
} return res;
} private:
bool judgetree(TreeNode* root1, TreeNode* root2){
if(root2==NULL)
return true; if(root1==NULL)
return false; if(root1->val!=root2->val)
return false; return judgetree(root1->left,root2->left)&&
judgetree(root1->right,root2->right);
}
};

以后看看能不能改进,避免递归调用。

11.栈的压入弹出

class Solution {
public:
bool IsPopOrder(vector<int> push, vector<int> pop) { bool res = false;
int len = push.size();
if (len != pop.size() || len <= ) return res; stack<int> sdata;
vector<int>::iterator nextpush = push.begin(), nextpop = pop.begin(); while (nextpop - pop.begin() < len)
{
while (sdata.empty() || sdata.top() != *nextpop)
{
if (nextpush - push.begin() == len)
break; sdata.push(*nextpush); ++nextpush;
} if (sdata.top() != *nextpop)
break; sdata.pop();
nextpop++;
} if (sdata.empty() && nextpop - pop.begin() == len)
res = true; return res;
}
};

12.二叉搜索树的后序遍历序列

class Solution {
public:
bool VerifySquenceOfBST(vector<int> sdata) { int len = sdata.size();
if (len <= ) return false; return judgeBST(sdata, , len - );
} private:
bool judgeBST(vector<int>& sdata, int left, int right) { if (right - left < ) return false; int i, j, root = sdata[right]; for (i = left;i < right;++i) {
if (sdata[i] > root)
break;
} for (j = i;j < right;++j) {
if (sdata[j] < root)
return false;
} bool leftsign = true, rightsign = true;
if (i > left) //表示有左子树
leftsign = judgeBST(sdata, left, i - ); if (i < right) //表示有右子树
rightsign = judgeBST(sdata, i, right - ); return (leftsign&&rightsign);
}
};

13.按之字形顺序打印二叉树

class Solution {
public:
vector<vector<int>> Print(TreeNode* root)
{
vector<vector<int>> res;
if (NULL == root)
return res; int i, left, right, nextlevel = , tobepush = ;
vector<int> vtmp;
std::queue<TreeNode*> nodes;
nodes.push(root); while (!nodes.empty())
{
TreeNode *nodetmp = nodes.front();
vtmp.push_back(nodetmp->val); if (nodetmp->left)
{
++nextlevel;
nodes.push(nodetmp->left);
} if (nodetmp->right)
{
++nextlevel;
nodes.push(nodetmp->right);
} nodes.pop();
--tobepush;
if ( == tobepush)
{
res.push_back(vtmp);
vtmp.clear();
tobepush = nextlevel;
nextlevel = ;
}
} for (i = ; i < res.size(); i += )
{
left = ;right = res[i].size() - ;
while (left < right)
{
swap(res[i][left], res[i][right]);
++left;--right;
}
}
return res;
} private:
void swap(int& a, int& b)
{
int tmp = a;a = b;b = tmp;
}
};

14.判断二叉树是否对称

class Solution {
public:
bool isSymmetrical(TreeNode* pRoot)
{
if (NULL == pRoot)
return true;
else return judgeSymmetrical(pRoot->left, pRoot->right);
} private:
bool judgeSymmetrical(TreeNode* left, TreeNode* right)
{
if (NULL == left&&NULL == right)
return true; if (NULL == left || NULL == right)
return false; if (left->val != right->val)
return false; //注意此处不能判断相等返回true,因为下面还要进行判断 return judgeSymmetrical(left->left, right->right)
&& judgeSymmetrical(left->right, right->left);
}
};

很完美的思路,通过前序序列进行判断。

15.二叉树的序列化和反序列化

class Solution {
public:
char* Serialize(TreeNode *root)
{
string str;
Serialize(root, str); int i,len = str.length();
char *res = new char[len + ];
for (i = ; i < len; i++)
res[i] = str[i];
res[i] = '\0';
return res;
} TreeNode* Deserialize(char *str)
{
if (NULL == str || *str == '\0')
return NULL; int left = ; string numstr(str); TreeNode* head = Deserialize(numstr, left);
return head;
} private: void Serialize(TreeNode *root, string& str)
{
if (NULL == root)
{
str += "#,"; return;
}
else
{
ostringstream ost;
ost << root->val;
str += ost.str() + ',';
} Serialize(root->left, str);
Serialize(root->right, str);
} bool readstr(string& str,int& left, int& num)
{
if (str[left] == '#')
{
left += ; //退后至下一个数字
return false;
}
else
{
string tmp;
while (str[left] != ',' && str[left] != '\0')
{
tmp += str[left++];
}
++left;
num = atoi(tmp.c_str());
return true;
}
} TreeNode* Deserialize(string& numstr,int& left)
{
int num;
if (readstr(numstr, left, num))
{
TreeNode* root = new TreeNode(num); root->left = Deserialize(numstr, left);
root->right = Deserialize(numstr, left);
return root;
}
return NULL;
}
};

16.二叉搜索树的第K个节点

class Solution {
public:
TreeNode* KthNode(TreeNode* pRoot, unsigned int k)
{
if (NULL == pRoot || k == )
return NULL; return KthTreeNode(pRoot, k);
} private:
TreeNode* KthTreeNode(TreeNode* root, unsigned int& k)
{
TreeNode* target = NULL; if (root->left != NULL)
target = KthTreeNode(root->left, k); if (NULL == target)
{
if (k == )
target = root;
--k;
} if (NULL == target&&root->right != NULL)
target = KthTreeNode(root->right, k); return target;
}
};

根据中序遍历的方式实现寻找。

剑指offer习题集2的更多相关文章

  1. 剑指offer习题集1

    1.打印二叉树 程序很简单,但是其中犯了一个小错误,死活找不到,写代码要注意啊 这里左右子树,要注意是node->left,结果写成root->left vector<int> ...

  2. 剑指offer习题集

    1.重载赋值运算符函数:(具体见代码) //普通做法 CMyString& CMyString::operator=(const CMyString& str) { if (this ...

  3. 剑指Offer面试题:1.实现Singleton模式

    说来惭愧,自己在毕业之前就该好好看看<剑指Offer>这本书的,但是各种原因就是没看,也因此错过了很多机会,后悔莫及.但是后悔是没用的,现在趁还有余力,把这本书好好看一遍,并通过C#通通实 ...

  4. 剑指Offer面试题:14.链表的倒数第k个节点

    PS:这是一道出境率极高的题目,记得去年参加校园招聘时我看到了3次,但是每次写的都不完善. 一.题目:链表的倒数第k个节点 题目:输入一个链表,输出该链表中倒数第k个结点.为了符合大多数人的习惯,本题 ...

  5. 《剑指offer》面试题12:打印1到最大的n位数

    面试题12:打印1到最大的n位数 剑指offer题目12,题目如下 输入数字n,按顺序打印出1到最大的n位十进制数,比如输入3,则打印出1,2,3一直到最大的三位数999 方法一 和面试题11< ...

  6. 《剑指offer》面试题11: 数值的整数次方

    面试题11: 数值的整数次方 剑指offer面试题11,题目如下 实现函数double power(double base,int exponent),求base的exponent次方, 不得使用库 ...

  7. 剑指 Offer 题目汇总索引

    剑指 Offer 总目录:(共50道大题) 1. 赋值运算符函数(或应说复制拷贝函数问题) 2. 实现 Singleton 模式 (C#) 3.二维数组中的查找 4.替换空格              ...

  8. 面试题目——《剑指Offer》

    1.把一个字符串转换成整数——<剑指Offer>P29 2.求链表中的倒数第k个结点——<剑指Offer>P30 3.实现Singleton模式——<剑指Offer> ...

  9. 剑指Offer:面试题20——顺时针打印矩阵(java实现)

    题目描述: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数 字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1, ...

随机推荐

  1. 深入理解gradle编译-Android基础篇

    深入理解gradle编译-Android基础篇 导读 Gradle基于Groovy的特定领域语言(DSL)编写的一种自动化建构工具,Groovy作为一种高级语言由Java代码实现,本文将对Gradle ...

  2. ajax对象属性withCredentials

    默认情况下,ajax跨源请求不提供凭据(cookie.HTTP认证及客户端SSL证明等).通过将设置ajax的withCredentials属性设置为true,可以指定某个请求应该发送凭据.如果服务器 ...

  3. hive的Query和Insert,Group by,Aggregations(聚合)操作

    1.Query (1)分区查询 在查询的过程中,采用那个分区来查询是通过系统自动的决定,但是必须是在分区列上基于where子查询. SELECT page_views.* FROM page_view ...

  4. 探索javascript----有关数组的常用方法

    与字符串的转换: str.split(","):将一个字符串以为英文逗号分割,返回一个数组: arr.join(","):返回用指定分隔符间隔的含所有数组元素的 ...

  5. UIRefreshControl自动刷新

    不知道UIRefreshController是什么的朋友可以参考iOS6新特征:UIRefreshControl[下拉刷新]使用示例 一文了解这是什么,这里只提怎么使用代码的方式触发UIRefresh ...

  6. 银光类似web visio的节点连线控件Essential Diagram免费下载地址

    Essential Diagram for Silverlight是一款功能强大的图解拓扑图控件,在XAML支持的情况下提供用户交互式地创建和编辑图解,支持数据绑定和多种布局,可以导出为多种文件格式等 ...

  7. Linux Kernel Version Numbering

    Because there are numerous revisions and releases of the Linux kernel and new ones are developed at ...

  8. CentOS 6.6 中中文输入法设置

    排版比较乱你,参见 https://www.zybuluo.com/Jpz/note/144597 Linux开发环境配置 安装完系统之后,我们需要设置中文输入法,中文输入法是系统自带的,设置步骤如下 ...

  9. cocoapod的下载安装解释

    本文不提供cocoapod的下载安装的流程,因为那些只要百度一下就有的东西,而是对里面的代码进行解释,希望对iOS小白安装cocoapod有帮助: 一.cocoapod是什么? 开发过程中,我们会用到 ...

  10. MySQL安装及主从配置

    系统环境:CentOS release 6.5 (Final)(最小化安装) MySQL版本:mysql-5.6.12 Cmake版本:cmake-2.8.4 说明:安装mysql先安装cmake(原 ...