【26-30】剑指offer
来源:互联网 发布:漫画配音软件 编辑:程序博客网 时间:2024/06/06 02:20
26.题目描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
注意:采用递归实现。注意指向指针的指针的使用。
#include <iostream>
using namespace std;
struct TreeNode {
intval;
structTreeNode *left;
structTreeNode *right;
TreeNode(intx) :
val(x),left(NULL), right(NULL) {
}
};
TreeNode* pre;
class Solution {
public:
TreeNode* Convert(TreeNode* pRootOfTree)
{
//调用遍历函数实现,二叉树序列换
TreeNode*pInitNodeLast = NULL;
ConvertNode(pRootOfTree,&pInitNodeLast);
//找出最左变的结点
TreeNode* pListHead = pInitNodeLast;
while(pRootOfTree!= NULL && pListHead->left != NULL)
{
pListHead= pListHead->left;
}
//返回链表头
returnpListHead;
}
voidConvertNode(TreeNode *root, TreeNode** pInitNodeLast)
{
//如果结点为NULL,则返回
if(root== NULL)
return;
//如果结点的左子节点不为NULL,则递归左子树
if(root->left!= NULL)
ConvertNode(root->left,pInitNodeLast);
//操作
TreeNode* pCurrent = root;
pCurrent->left= *pInitNodeLast;
if((*pInitNodeLast)!= NULL)
(*pInitNodeLast)->right= pCurrent;
(*pInitNodeLast)= pCurrent;
//如果右子节点不为NULL,则遍历右子树
if(root->right!= NULL)
ConvertNode(root->right,pInitNodeLast);
}
//创建二叉树
TreeNode* CreateTree()
{
intval = 0;
cout<<"Pleaseinput val(-1):";
cin>>val;
if(val== -1)
returnNULL;
TreeNode*root = new TreeNode(val);
root->left=CreateTree();
root->right=CreateTree();
returnroot;
}
//前序打印二叉树
voidPrePrintTree(TreeNode *root)
{
if(root== NULL)
return;
cout<<root->val<<"";
PrePrintTree(root->left);
PrePrintTree(root->right);
}
};
int main()
{
Solutions;
TreeNode*root = s.CreateTree();
s.PrePrintTree(root);
cout<<endl;
TreeNode*ListHead = s.Convert(root);
TreeNode*temp = ListHead;
while(temp!= NULL)
{
cout<<temp->val<<"";
temp= temp->right;
}
return0;
}
27.题目描述
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。结果请按字母顺序输出。
输入描述:
输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
思路:采用递归实现。1.从字符串中选择第一个字符,分别与后面的字符进行替换,若满足到达字符串末尾,则保存该字符串;2.递归;3.将替换的字符还原。若有重复则继续循环。具体见代码:
#include<iostream>
#include<vector>
#include<string>
using namespace std;
class Solution {
public:
voidPermutation(char *pStr, char *pBegin,vector<string> &perm)
{
if(*pBegin== '\0')
{
//cout<<pStr<<endl;
perm.push_back((string)pStr);
}
//将前面的字符与后面的字符一次交换
for(char*pCh = pBegin; *pCh != '\0'; pCh++)
{
if(pCh!= pBegin && *pCh == *pBegin)
continue;
// char tempChar = *pBegin;
// *pBegin = *pCh;
// *pCh = tempChar;
chartempChar = *pCh;
char*p = pCh;
while(p!= pBegin)
{
*p= *(p-1);
p--;
}
*pBegin= tempChar;
Permutation(pStr,pBegin+1, perm);
// tempChar = *pBegin;
// *pBegin = *pCh;
// *pCh = tempChar;
tempChar= *pBegin;
p= pBegin;
while(p!= pCh)
{
*p= *(p+1);
p++;
}
*p= tempChar;
}
}
vector<string> Permutation(string str)
{
//如果输入的字符串为NULL,则返回
if(str.empty())
returnvector<string>(0);
//如果输入字符串不为NULL,则递归获取排列组合
vector<string>perm;
Permutation(const_cast<char*>(str.c_str()),const_cast<char *>(str.c_str()), perm);
returnperm;
}
};
int main()
{
stringstr1 = "123";
Solutions;
vector<string>perm = s.Permutation(str1);
cout<<endl;
vector<string>::iteratorite = perm.begin();
for(;ite != perm.end(); ite++)
cout<<*ite<<endl;
return 0;
}
28.题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
思路:采用快速排序算法。由于数字出现的次数超过了数组的一半,所以当取数轴小于数组的一半,则在右侧只进行右侧排序,否则在左侧进行排序。
#include <iostream>
#include <vector>
using namespace std;
bool g_bInputInvalid = false;
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers)
{
//检查numbers是否满足合法
if(ChenkInvalidArray(numbers))
return0;
returnQuickSortMoreThanHalfNum(numbers, 0, numbers.size()-1);
}
intQuickSortMoreThanHalfNum(vector<int> &numbers, int start, int end)
{
//获取取数轴的值
intpivot;
intmid = (end - start + 1)>>1;
pivot = Partition(numbers, start, end);
while(pivot!= mid)
{
if(pivot< mid)
{
start= pivot + 1;
pivot= Partition(numbers, start, end);
}
else
{
end= pivot - 1;
pivot= Partition(numbers, start, end);
}
}
intresult = numbers[mid];
if(!CheckMoreThanHalf(numbers,result))
return0;
returnresult;
}
intPartition(vector<int> &numbers, int start, int end)
{
intpivotkey;
inttemp = pivotkey = numbers[start];
while(start< end)
{
while(start< end && numbers[end] >= pivotkey)
end--;
numbers[start]= numbers[end];
while(start< end && numbers[start] <= pivotkey)
start++;
numbers[end]= numbers[start];
}
numbers[start]= temp;
returnstart;
}
boolChenkInvalidArray(vector<int> numbers)
{
g_bInputInvalid= false;
if(numbers.size()== 0)
g_bInputInvalid= true;
returng_bInputInvalid;
}
boolCheckMoreThanHalf(vector<int> numbers, int result)
{
inttimes = 0;
vector<int>::iteratorite = numbers.begin();
for(; ite!=numbers.end();ite++)
{
if(*ite== result)
times++;
}
boolisMoreThanHalf = true;
if(times*2<= numbers.size())
{
isMoreThanHalf= false;
g_bInputInvalid=true;
}
returnisMoreThanHalf;
}
};
int main()
{
freopen("data.txt","r",stdin);
vector<int>numbers(9);
vector<int>::iteratorite = numbers.begin();
for(; ite != numbers.end(); ite++)
cin>>*ite;
Solutions;
cout<<"Thenum is:"<<s.MoreThanHalfNum_Solution(numbers)<<endl;
return0;
}
29.题目描述
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
思路:按照上一题的思路进行。注意处理边界。也可以采用红黑树来实现。
#include <iostream>
#include <vector>
using namespace std;
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, intk)
{
//检查numbers是否满足合法
vector<int>result(k);
QuickSortMoreThanHalfNum(input,k, result);
returnresult;
}
voidQuickSortMoreThanHalfNum(vector<int> &numbers, int k,vector<int> &result)
{
if(numbers.size()== 0 || k > numbers.size() || k <= 0)
{
result.resize(0);
return;
}
//获取取数轴的值
intstart = 0;
intend = numbers.size()-1;
intpivot = Partition(numbers, start, end);
while(pivot!= k-1)
{
if(pivot> k-1)
{
end= pivot - 1;
pivot= Partition(numbers, start, end);
}
else
{
start= pivot + 1;
pivot= Partition(numbers, start, end);
}
}
for(inti= 0; i < k; i++)
{
cout<<numbers[i]<<endl;
result[i]= numbers[i];
}
}
intPartition(vector<int> &numbers, int start, int end)
{
intpivotkey;
inttemp = pivotkey = numbers[start];
while(start< end)
{
while(start< end && numbers[end] >= pivotkey)
end--;
numbers[start]= numbers[end];
while(start< end && numbers[start] <= pivotkey)
start++;
numbers[end]= numbers[start];
}
numbers[start]= temp;
returnstart;
}
};
int main()
{
freopen("data.txt","r",stdin);
vector<int>numbers(13);
vector<int>::iteratorite = numbers.begin();
for(; ite != numbers.end(); ite++)
cin>>*ite;
Solutions;
vector<int>temp = s.GetLeastNumbers_Solution(numbers, 6);
ite= temp.begin();
for(;ite != temp.end(); ite++)
cout<<*ite<<"";
return0;
}
30.题目描述
HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。你会不会被他忽悠住?
注意:求取连续数组的最大和,只需要俩个参数,一个记录数组的当前求和值,另一个记录数组求和的最大值。当当前求和值小于或者等于0时更新当前求和值为当前数组对应的元素值,否则进行累加。当当前求和值大于记录数组求和的最大值,则更新记录数组求和的最大值。
#include<iostream>
#include<vector>
using namespace std;
bool g_IvalidInput = false;
class Solution {
public:
int FindGreatestSumOfSubArray(vector<int> array) {
//如果数组为NULL,则返回0
if(array.size()== 0)
{
g_IvalidInput= true;
return0;
}
//如果数组不为NUL,则求取连续子数组的最大和
intnSum = 0;
intnSumOfSubarray = 0x80000000;
cout<<nSumOfSubarray<<endl;
vector<int>::iteratorite = array.begin();
for(;ite != array.end(); ite++)
{
//如果和小于等于0时,则舍弃之前的求和
if(nSum<= 0)
nSum= *ite;
else
nSum+= *ite;
if(nSum> nSumOfSubarray)
nSumOfSubarray= nSum;
}
returnnSumOfSubarray;
}
};
int main()
{
vector<int>array(8);
freopen("data.txt","r", stdin);
vector<int>::iteratorite = array.begin();
for(;ite != array.end(); ite++)
{
cin>>*ite;
}
Solutions;
cout<<s.FindGreatestSumOfSubArray(array)<<endl;
return0;
}- 【26-30】剑指offer
- 剑指Offer-26
- 剑指Offer-30
- 剑指offer面试题26
- 剑指offer面试题30
- 剑指offer(21-30)
- 【剑指offer】21-30题
- 剑指offer 试题21~30
- 剑指offer面试题 java解答26-30
- 剑指offer学习笔记(Java实现)(26-30)
- 剑指OFFER
- 剑指offer
- 剑指Offer
- 剑指offer
- 剑指Offer
- 剑指offer
- 剑指offer
- 剑指offer
- Codeforces 554B:Ohana Cleans Up(思维+水题)
- Kafka的应用——环信业务优化
- 使用Junit4对由Maven管理的Spring项目进行单元测试
- Jquery李炎恢——37,38对话框UI【3】【4】
- RandomAccessFile的应用
- 【26-30】剑指offer
- 1412: [ZJOI2009]狼和羊的故事
- Android无法显示超大图问题的探索
- iOS-View适应文字
- Android如何判断应用程序是安装在手机内存中还是SD卡
- 博客已迁移至github pages
- Gensee Android SDK(一)组成结构
- 贪心算法
- HDU - 1998 奇数阶魔方