剑指offer习题集1
1.打印二叉树
程序很简单,但是其中犯了一个小错误,死活找不到,写代码要注意啊
这里左右子树,要注意是node->left,结果写成root->left
vector<int> PrintFromTopToBottom(TreeNode *root) { vector<int> res;
if (NULL == root)
return res; TreeNode* node;
deque<TreeNode*> tmp;
tmp.push_back(root); while (tmp.size()) { node = tmp.front();
res.push_back(node->val);
tmp.pop_front(); if (node->left)
tmp.push_back(node->left);
if (node->right)
tmp.push_back(node->right);
}
return res;
}
2.求1+2+...+n
class A{
public:
A(){
++n;sum+=n;
}
static int getsum(){
return sum;
}
static void reset(){
n=;sum=;
}
~A(){} private:
static int n;
static int sum;
}; int A::n=;
int A::sum=; class Solution {
public: int Sum_Solution(int n) { A::reset(); //必不可少,测试集会重复运行 A* tmp=new A[n];
delete[] tmp; return A::getsum();
}
};
3.二叉树镜像
class Solution {
public:
void Mirror(TreeNode *pRoot) { if(NULL==pRoot||(NULL==pRoot->left&&NULL==pRoot->right))
return; mirrorset(pRoot);
} void mirrorset(TreeNode* root){ if(NULL==root||(NULL==root->left&&NULL==root->right))
return; TreeNode *tmp=root->left;
root->left=root->right;
root->right=tmp; if(root->left)
mirrorset(root->left);
if(root->right)
mirrorset(root->right);
}
};
4.合并两个排序的链表
剑指offer书上用的是递归,感觉不必那么麻烦,用一个循环就可以解决。
ListNode1* Merge(ListNode1* pHead1, ListNode1* pHead2)
{
//避免空指针
if (NULL == pHead1 || NULL == pHead2)
return NULL == pHead1 ? pHead2 : pHead1; //选取两个链表中的最小值作为链表头
bool sign[] = { false };
ListNode1 *p1 = pHead1, *p2 = pHead2, *p3, *res;
if (p1->val < p2->val) {
res = p1;p3 = res;p1 = p1->next;sign[] = true;
}
else {
res = p2;p3 = res;p2 = p2->next;sign[] = true;
} while (p1&&p2) {
if (p1->val < p2->val) {
if (sign[]) {
p1 = p1->next;
p3 = p3->next;
}
else {
p3->next = p1;
p1 = p1->next;
p3 = p3->next;
}
sign[] = true;sign[] = false;
}
else {
if (sign[]) {
p2 = p2->next;
p3 = p3->next;
}
else {
p3->next = p2;
p2 = p2->next;
p3 = p3->next;
}
sign[] = false;sign[] = true;
}
} if (p1) {
p3->next = p1;
}
else if (p2) {
p3->next = p2;
} return res;
}
5.复杂链表的复制
/*
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(NULL==pHead)
return NULL; //复制链表节点,并嵌入原链表
RandomListNode *p1=pHead,*p2=pHead,*res;
while(p1){
RandomListNode *temp=new RandomListNode(p1->label);
temp->next=p1->next;
p1->next=temp; if(NULL==temp->next)
break;
else p1=temp->next;
} //复制随机指针
p1=pHead;
while(p1){
p2=p1->random;
p1=p1->next;
p1->random=p2;
p1=p1->next;
} //拆分链表
p1=pHead;p2=p1->next;res=p2;
while(p1&&NULL!=p2->next){
p1->next=p2->next;
p1=p1->next;
p2->next=p1->next;
p2=p2->next;
}
p1->next=NULL; return res;
}
};
6.顺时针打印矩阵
void print(const vector<vector<int>>& matrix, const int& len1, const int& len2, const int& n, vector<int>& res) { int i, endx = len1 - - n, endy = len2 - - n; //从左至右存储
for (i = n;i <= endy;++i) {
res.push_back(matrix[n][i]);
} //从上至下存储
if (n < endx) {
for (i = n + ;i <= endx;++i)
res.push_back(matrix[i][endy]);
} //从右至左打印
if (n < endx&&n < endy) {
for (i = endy - ;i >= n;--i)
res.push_back(matrix[endx][i]);
} //从下至上打印
if (n < endx - && n < endy) {
for (i = endx - ;i >= n + ;--i)
res.push_back(matrix[i][n]);
}
} vector<int> printMatrix(vector<vector<int>>& matrix) { vector<int> res;
int len1 = matrix.size(), len2, n = ; if ( == len1) {
return res;
}
else if ( == len1) {
return matrix[];
}
else {
len2 = matrix[].size();
} while ( * n < len1 && * n < len2) {
print(matrix, len1, len2, n, res);
++n;
} return res;
}
在VS上写程序真的是很简单,各种智能提示,在其他IDE上写程序,就得时刻注意。。。结果还是不容易找到错误
7.不能用加减乘除做加法
class Solution {
public:
int Add(int num1, int num2)
{
int sum1,sum2; do{
sum1=num1^num2;
sum2=(num1&num2)<<; num1=sum1;
num2=sum2;
}while(num2!=); return sum1;
}
};
日了够了,就不能一遍通过,左移右移竟然能犯错误。
8.翻转字符串
注意j值的变化,机试时不带调试,实在是无语啊
class Solution {
public:
string ReverseSentence(string str) { int len=str.length();
if(len<=) return str; int i,j,left,right; //首先翻转整条语句
reverse(str,,len-); //逐个翻转单词
left=;right=;
for(i=;i<len;i++){
if(str[i]!=' '){
left=i;
for(j=i+;j<=len;j++){
if(str[j]==' '||str[j]=='\0'){
right=j-;
break;
}
}
reverse(str,left,right);
i=j; //从当前为空格字符运行
}
} return str;
} private:
void reverse(string& str,int left,int right){ if(left<||right<||(right-left)<=)
return; char temp;
while(left<right){ temp=str[left];
str[left]=str[right];
str[right]=temp; ++left;
--right;
}
}
};
9.数组在排序数组中出现的次数
class Solution {
public:
int GetNumberOfK(vector<int> data ,int k) { bool sign=false;
int len=data.size();
if(==len) return ;
int left=,right=len-,mid; //通过二分查找法先缩小搜索范围
while(left<=right){ //注意二分查找法此处是等号,否则应对只有一个元素,岂不是呵呵了
mid=(left+right)>>;
if(data[mid]==k){
sign=true;break;
}else if(data[mid]<k){
left=mid+;
}else{
right=mid-;
}
}
if(!sign) return ; //确保数组中包含此数据 return getlastk(data,len,k,mid,right)-getfirstk(data,k,left,mid)+;
} int getfirstk(vector<int>& data,const int& k,int left,int right){ int mid=(left+right)>>;
int midval=data[mid]; if(midval==k){
if((mid>&&data[mid-]!=k)||mid==){
return mid;
}else
right=mid-;
}else if(midval<k){
left=mid+;
}else{
right=mid-;
} return getfirstk(data,k,left,right);
} int getlastk(vector<int>& data,const int& len,const int& k,int left,int right){ int mid=(left+right)>>;
int midval=data[mid]; if(midval==k){
if((mid<len-&&data[mid+]!=k)||mid==len-){
return mid;
}else{
left=mid+;
}
}else if(midval<k){
left=mid+;
}else{
right=mid-;
} return getlastk(data,len,k,left,right);
} };
10.二叉树的下一节点(看着答案做的,还需重新做)
class Solution {
public:
TreeLinkNode* GetNext(TreeLinkNode* pNode)
{
if(NULL==pNode)
return NULL; TreeLinkNode* pnext=NULL; if(pNode->right!=NULL){ TreeLinkNode *right=pNode->right;
while(right->left){
right=right->left;
}
pnext=right;
}else if(pNode->next){
TreeLinkNode *curr=pNode;
TreeLinkNode *parent=curr->next;
while(parent!=NULL&&curr==parent->right){
curr=parent;
parent=parent->next;
}
pnext=parent;
}else{
//父节点无右子树
} return pnext;
}
};
11.按行打印二叉树
运行一直出错,还是找不到错误,后续才发现少了return res;
在线测试也不会提醒这个错误的,简直对自己无语了啊。
vector<vector<int> > Print_test(BinaryTreeNode* pRoot) { vector<vector<int>> res;
if (NULL == pRoot)
return res; int print = , nextlevel = ;
BinaryTreeNode* temp;
std::queue<BinaryTreeNode*> nodes;
std::vector<int> tval;
nodes.push(pRoot); while (nodes.size()) { temp = nodes.front();
tval.push_back(temp->m_nValue);
if (temp->m_pLeft) {
nodes.push(temp->m_pLeft); ++nextlevel;
}
if (temp->m_pRight) {
nodes.push(temp->m_pRight); ++nextlevel;
}
nodes.pop(); --print;
if (!print) { //通过队列记录数值,并在读取完一层之后进行清空
vector<int> val;
for (int i = ;i<tval.size();++i) {
val.push_back(tval[i]);
}
tval.clear();
res.push_back(val); print = nextlevel;
nextlevel = ;
}
} return res;
}
以后一定先写return res;
还有就是声明指针的时候一定记住初始化为NULL。
12.找最小的k个数
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) { int len=input.size();
if(len<k){
vector<int> res;return res;
}else if(len==k){
return input;
} QuickSort(input);
vector<int> data;
for(int i=;i<k;++i){
data.push_back(input[i]);
}
return data;
} void Qsort(vector<int>& data,int left,int right)
{
if (left < right)
{
//此步保证data[pivot]大于左边的元素小于右边的元素,arry[pivot]被正确安排
int pivot = partition(data, left, right);
Qsort(data, left, pivot - );
Qsort(data, pivot + , right);
}
} void QuickSort(vector<int>&data)
{
Qsort(data, , data.size() - );
} void swap(int&a, int&b) {
int t = a;a = b;b = t;
} int partition(vector<int>& data,const int& start,const int& end){ int left=start,right=end;
int pivot=data[left]; while(left<right){
while(left<right&&data[right]>=pivot)
--right;
swap(data[left],data[right]); while(left<right&&data[left]<=pivot)
++left;
swap(data[left],data[right]);
}
return left;
}
};
快排必须将第一个数值作为基准,当然,你要想选取中间数值,可以将中间数值与第一个数值进行交换。
13.反转链表
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) { if(NULL==pHead||NULL==pHead->next)
return pHead; ListNode* reversehead=NULL;
ListNode* prenode=NULL;
ListNode* currnode=pHead;
ListNode* nextnode=NULL; while(currnode){ nextnode=currnode->next;
if(NULL==nextnode){
reversehead=currnode;
} currnode->next=prenode; prenode=currnode;
currnode=nextnode;
} return reversehead;
}
};
14.调整数组顺序,奇数位于偶数之前
class Solution {
public:
void swap(int& a,int& b){
int t=a;a=b;b=t;
} void reOrderArray(vector<int> &array) { int len=array.size();
if(==len||==len)
return; int left=,right=len-;
while(left<right){ while(left<right&&array[left]%==)
++left; while(left<right&&array[right]%==)
--right; if(left<right)
swap(array[left],array[right]);
}
}
};
不过此方法会改变奇数与奇数,偶数与偶数之间的相对关系。
15.数组中出现次数超过一半的数字
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) { int len=numbers.size();
if(==len)
return ;
else if(==len) return numbers[];
else if(len<=) return numbers[]; int index,start=,end=len-;
int mid=len>>;
index=partition(numbers,start,end);
while(index!=mid){
if(index>mid){
end=index-;
index=partition(numbers,start,end);
}else{
start=index+;
index=partition(numbers,start,end);
}
} if(judge(numbers,numbers[index],len)){
return numbers[index];
}else return ;
} private:
void swap(int& a,int& b){
int t=a;a=b;b=t;
} //此处因为调用函数确保了鲁棒性,故此处不添加相关检验
int partition(vector<int>& num,const int& start,const int& end){ int left=start,right=end,pivot=num[start]; while(left<right){ while(left<right&&num[right]>=pivot)
--right;
swap(num[left],num[right]); while(left<right&&num[left]<=pivot)
++left;
swap(num[left],num[right]);
}
return left;
} bool judge(vector<int>& num,const int&k,const int& len){ int i,n=;
for(i=;i<len;i++){
if(num[i]==k){
++n;
}
} return (n>len/)?true:false;
}
};
此题还是犯了错误,一个是没有判断中位数究竟是不是在数组中超过一半,即先天条件满不满足。
另外一个就是数组维数为1的时候,应该返回此数字,因为明显满足条件。。。
16.二维数组的寻找
class Solution {
public:
bool Find(vector<vector<int> > array,int target) { int i,j,len=array.size(); //鲁棒性检查
if(==len) return false;
for(i=;i<len;++i){
if(array[i].size()!=len)
return false;
}
if(array[][]>target)
return false;
if(array[len-][len-]<target)
return false; for(j=len-;j>=;--j){ //数据不在当前列,跳出循环
if(target<array[][j]||target>array[len-][j])
continue; for(i=;i<len;++i){
if(target==array[i][j])
return true;
}
} return false;
}
};
起始这个有更为优化的方式,我是通过列去寻找,有设置while循环,缩减行和列的数值,在逐渐缩小的块状区域寻找
剑指offer习题集1的更多相关文章
- 剑指offer习题集2
1.把数组排成最小的数 class Solution { public: static bool compare(const string& s1, const string& s2) ...
- 剑指offer习题集
1.重载赋值运算符函数:(具体见代码) //普通做法 CMyString& CMyString::operator=(const CMyString& str) { if (this ...
- 剑指Offer面试题:1.实现Singleton模式
说来惭愧,自己在毕业之前就该好好看看<剑指Offer>这本书的,但是各种原因就是没看,也因此错过了很多机会,后悔莫及.但是后悔是没用的,现在趁还有余力,把这本书好好看一遍,并通过C#通通实 ...
- 剑指Offer面试题:14.链表的倒数第k个节点
PS:这是一道出境率极高的题目,记得去年参加校园招聘时我看到了3次,但是每次写的都不完善. 一.题目:链表的倒数第k个节点 题目:输入一个链表,输出该链表中倒数第k个结点.为了符合大多数人的习惯,本题 ...
- 《剑指offer》面试题12:打印1到最大的n位数
面试题12:打印1到最大的n位数 剑指offer题目12,题目如下 输入数字n,按顺序打印出1到最大的n位十进制数,比如输入3,则打印出1,2,3一直到最大的三位数999 方法一 和面试题11< ...
- 《剑指offer》面试题11: 数值的整数次方
面试题11: 数值的整数次方 剑指offer面试题11,题目如下 实现函数double power(double base,int exponent),求base的exponent次方, 不得使用库 ...
- 剑指 Offer 题目汇总索引
剑指 Offer 总目录:(共50道大题) 1. 赋值运算符函数(或应说复制拷贝函数问题) 2. 实现 Singleton 模式 (C#) 3.二维数组中的查找 4.替换空格 ...
- 面试题目——《剑指Offer》
1.把一个字符串转换成整数——<剑指Offer>P29 2.求链表中的倒数第k个结点——<剑指Offer>P30 3.实现Singleton模式——<剑指Offer> ...
- 剑指Offer:面试题20——顺时针打印矩阵(java实现)
题目描述: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数 字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1, ...
随机推荐
- Material Design之TextInputLayout使用示例
Google在2015的IO大会上,给我们带来了更加详细的Material Design设计规范,同时,也给我们带来了全新的Android Design Support Library,在这个supp ...
- AngularJS向指令传递数据
我今天要实现的功能是利用AngularJS来完成客户端过滤器. list.html页面主要代码如下: ...... <div class='tj_con_tr_ipt' ng-init=&quo ...
- warning: incompatible implicit declaration of built-in function ‘exit’
出现这个错误,一般是程序中某个函数没有include相关的文件. EG. 出现这个错误是因为要使用exit()应该包含stdlib.h文件
- unity5.3.4之no android module loaded
参考http://www.cnblogs.com/shenggege/p/5165616.html 最近从unity5.1.3升级到5.3.4的时候,发现有个问题: system.io.file' d ...
- Zyxel Switch-How to block a fake DHCP server without enabling DHCP snooping?
How to block a fake DHCP server without enabling DHCP snooping? Scenario How to block a fake DHCP se ...
- PHP性能分析 - ngnx日志分析
最终结果展示图: 图解:响应时间在40ms以内的请求数占请求总量的7%,40到80ms的的请求数占32.9%,依次类推... 性能问题有很多种可能,普通的情况通过xhprof可查得主要的性能损耗.但有 ...
- C语言数组初始化
例如: int a[15] = {0}; 第一种,编译器会把第一个初始化值赋给数组的第一个元素,然后用0赋给其余的元素.如果没有给出初始值,编译器不会去做初始化工作.这样简洁的方式让代码更加高效. 还 ...
- Codeforces Round #163 (Div. 2)
A. Stones on the Table \(dp(i)\)表示最后颜色为\(i\)的最长长度. B. Queue at the School 模拟. C. Below the Diagonal ...
- 外观模式(Facade Pattern)
一.引言 在软件开发过程中,客户端程序经常会与复杂系统的内部子系统进行耦合,从而导致客户端程序随着子系统的变化而变化,然而为了将复杂系统的内部子系统与客户端之间的依赖解耦,从而就有了外观模式,也称作 ...
- 论文笔记之:A CNN Cascade for Landmark Guided Semantic Part Segmentation
A CNN Cascade for Landmark Guided Semantic Part Segmentation ECCV 2016 摘要:本文提出了一种 CNN cascade (CNN ...