【31-35】剑指offer
来源:互联网 发布:jsp调用java显示图片 编辑:程序博客网 时间:2024/05/23 14:21
31.题目描述
求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数。
思路:假设输入的数据为21345
first:代表第一位数据
numFirstDigit:代表高位1的个数
numOtherDigit:代表其他为1的个数
numRecusive:代表递归求取1的个数
如果first>1: numFirstDigit=10^(length-1)
如果first==1: numFirstDigit=atoi(strN+1)+1;
numOtherDigit = first*(length-1)*10^(length-2);
递归求取:numRecusive = NumberOf1(strN+1);
具体详见程序:
#include <iostream>
using namespace std;
class Solution {
public:
int NumberOf1Between1AndN_Solution(int n)
{
//如果输入大数据小于等于0,则返回0
if(n<= 0)
return0;
//将数据转化成字符串
charstrN[50];
sprintf(strN,"%d", n);
//返回1出现的次数
returnNumberOf1(strN);
}
intNumberOf1(const char * strN)
{
//检查输入的数据的合法性
if(!strN|| *strN < '0' || *strN > '9' || *strN == '\0')
return0;
intfirst = *strN - '0';
unsignedint length = static_cast<unsigned int>(strlen(strN));
//如果输入的数据是1位数,则有以下两种情况
if(length== 1 && first == 0)
return0;
if(length== 1 && first > 0)
return1;
//如果数据的数据是多为位数,则分三种情况
intnumFirstDigit = 0;
if(first> 1)
numFirstDigit= PowerBase10(length - 1);
elseif(first == 1)
numFirstDigit= atoi(strN+1)+1;
intnumOtherDigit = first*(length - 1)*PowerBase10(length - 2);
intnumRecusive = NumberOf1(strN+1);
returnnumFirstDigit + numOtherDigit + numRecusive;
}
intPowerBase10(unsigned int n)
{
intresult = 1;
for(unsignedint i = 0; i < n; i++)
{
result*= 10;
}
returnresult;
}
};
int main()
{
Solutions;
cout<<s.NumberOf1Between1AndN_Solution(10)<<endl;
cout<<s.NumberOf1Between1AndN_Solution(101)<<endl;
cout<<s.NumberOf1Between1AndN_Solution(1032)<<endl;
cout<<s.NumberOf1Between1AndN_Solution(21345)<<endl;
return0;
}
32.题目描述
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
思路:采用库函数qsort算法,并添加比较函数compare。具体实现见代码:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
const int g_MaxNumberLength = 10;
int compare(const void *strNumber1, constvoid *strNumber2)
{
char g_StrCombine1[g_MaxNumberLength*2 + 1]={'\0'};
charg_StrCombine2[g_MaxNumberLength*2 + 1]={'\0'};
strcpy(g_StrCombine1,*(constchar **)strNumber1);
strcat(g_StrCombine1,*(constchar **)strNumber2);
strcpy(g_StrCombine2,*(constchar **)strNumber2);
strcat(g_StrCombine2,*(constchar **)strNumber1);
returnstrcmp(g_StrCombine1, g_StrCombine2);
}
class Solution {
public:
string PrintMinNumber(vector<int> numbers) {
string str = "";
int length = numbers.size();
inti = 0;
//如果数组为NULL,则返回空字符串
if(length== 0)
returnstr;
//如果数组有小于0的数,则返回空字符串
vector<int>::iterator ite =numbers.begin();
for(;ite != numbers.end(); ite++)
if(*ite< 0)
returnstr;
//如果字符串不为空,且数组满足要求
//char**strNumbers = (char **)(new int[length]); //书上该句存在问题?下面两种内存分配都可以
//char**strNumbers = new char*[4*length];
char**strNumbers = (char **)(new int*[length]);
intcount = 0;
for(i= 0; i < length; i++)
{
if(numbers[i]== 0)
continue;
strNumbers[count]= new char[g_MaxNumberLength + 1];
sprintf(strNumbers[count],"%d",numbers[i]);
count++;
}
//调用库函数进行排序
qsort(strNumbers,count, sizeof(char*), compare);
//输出排序后的数据
for(i= 0; i < count; i++)
{
str+= strNumbers[i];
}
//清理分配的内存
for(i= 0; i < count; i++)
delete[]strNumbers[i];
delete[]strNumbers;
returnstr;
}
};
int main()
{
vector<int>array(5);
freopen("data.txt","r", stdin);
vector<int>::iteratorite = array.begin();
for(; ite != array.end(); ite++)
cin>>*ite;
Solutions;
cout<<s.PrintMinNumber(array)<<endl;
return0;
}
33.题目描述
把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
#include <iostream>
using namespace std;
class Solution {
public:
intMin(int a, int b, int c)
{
intmin = (a > b) ? b:a;
return(min > c)? c:min;
}
int GetUglyNumber_Solution(int index) {
if(index<= 0)
return0;
//存放丑数
int*pUglyNumber = new int[index];
if(pUglyNumber== NULL)
return0;
pUglyNumber[0]= 1;
intnextUglyNumber = 1;
int*p2 = pUglyNumber;
int*p3 = pUglyNumber;
int*p5 = pUglyNumber;
while(nextUglyNumber< index)
{
intmin = Min(*p2*2, *p3*3, *p5*5);
pUglyNumber[nextUglyNumber]= min;
cout<<min<<endl;
while((*p2)*2<= pUglyNumber[nextUglyNumber])
p2++;
while((*p3)*3<= pUglyNumber[nextUglyNumber])
p3++;
while((*p5)*5<= pUglyNumber[nextUglyNumber])
p5++;
nextUglyNumber++;
}
intUglyNum = pUglyNumber[nextUglyNumber-1];
delete[] pUglyNumber;
returnUglyNum;
}
};
int main()
{
Solutions;
cout<<s.GetUglyNumber_Solution(1500)<<endl;
return0;
}
34.题目描述
在一个字符串(1<=字符串长度<=10000,全部由大写字母组成)中找到第一个只出现一次的字符,并返回它的位置
思路:创建哈希表,实现查找时间复杂度为O(1).第一次遍历,获得每个字符出现的次数;第二次遍历获得只出现一且第一次出现的字符。通过变量position来记录字符的位置。具体实现见代码:
#include<iostream>
using namespace std;
class Solution {
public:
int FirstNotRepeatingChar(string str) {
int hasTable[256];
for(inti = 0; i < 256; i++)
hasTable[i]= 0;
char*pCh = &str[0];
while(*pCh!= '\0')
{
hasTable[*pCh]++;
pCh++;
}
pCh= &str[0];
intposition = -1;
while(*pCh!= '\0')
{
position++;
if(hasTable[*pCh]== 1)
returnposition;
pCh++;
}
return-1;
}
};
int main()
{
Solutions;
cout<<s.FirstNotRepeatingChar("abdgesdaga")<<endl;
return0;
}
35.题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。即输出P%1000000007
输入描述:
题目保证输入的数组中没有的相同的数字
数据范围:
对于%50的数据,size<=10^4
对于%75的数据,size<=10^5
对于%100的数据,size<=2*10^5
输入例子:
1,2,3,4,5,6,7,0
输出例子:
7
思路:采用基于归并排序的方式统计逆序对的数据,具体见代码(注意数据类型的选择):
#include <iostream>
#include <vector>
using namespace std;
class Solution {
public:
int InversePairs(vector<int> data) {
//如果数组的长度为0,则返回0
if(data.size()== 0)
return0;
//否则采用基于归并的方法统计逆序对的数目
vector<int>copy(data.size());
copy= data;
longint count = InversePairsCores(data, copy, 0, data.size()-1);
returncount%1000000007;
}
longint InversePairsCores(vector<int> &data, vector<int> ©,int start, int end)
{
//当start==end时,返回0
if(start== end)
{
copy[start]= data[start];
return0;
}
//否则,递归左右两边的数组
intlength = (end - start)/2;
longint left = InversePairsCores(copy, data, start, start+length);
longint right = InversePairsCores(copy, data, start+length+1, end);
//进行归并计数
longint count = MergeCount(copy, data, start, end, length);
returncount + left + right;
}
longint MergeCount(vector<int> &data, vector<int> ©, intstart, int end, int length)
{
inti = start + length;
intj = end;
longint count = 0;
intindexCopy = end;
while(i>= start && j >= start + length + 1)
{
//满足逆序对的条件,count++,且将最大的数据拷贝到copy中。
if(data[i]> data[j])
{
copy[indexCopy--]= data[i--];
count+= j - start - length; //这一句不是很明白??
}
else//否则,直接拷贝,count不变
{
copy[indexCopy--]= data[j--];
}
}
//若未归并完,则继续归并
for(;i >= start; i--)
copy[indexCopy--]= data[i];
for(;j >= start+length+1; j--)
copy[indexCopy--]= data[j];
returncount;
}
};
int main()
{
vector<int>data(4);
freopen("data.txt","r",stdin);
vector<int>::iteratorite = data.begin();
for(;ite != data.end(); ite++)
{
cin>>*ite;
}
Solutions;
cout<<s.InversePairs(data)<<endl;
return0;
}- 【31-35】剑指offer
- 剑指Offer --> Questions 35
- 剑指Offer-35
- 剑指Offer-31
- 剑指offer面试题35
- 剑指offer面试题31
- 剑指offer(31-40)
- 【剑指offer】31-40题
- 剑指offer 试题31~40
- 剑指offer面试题 java解答31-35
- 剑指OFFER
- 剑指offer
- 剑指Offer
- 剑指offer
- 剑指Offer
- 剑指offer
- 剑指offer
- 剑指offer
- AOJ 351 rmq或 基础线段树 求解
- 387.leetcode First Unique Character in a String(easy)[统计字符串字符次数]
- 杭电2091空心三角形
- python装饰器的学习
- Python3爬虫学习笔记2.1——爬文字-糗事百科
- 【31-35】剑指offer
- bzoj1251(splay序列操作)
- Java的HashMap和HashTable
- Parsing XML Data
- HDU 4553 约会安排(线段树区间合并&优先级)
- 笔迹宽度估计的低质量文本图像二值化(Robust Document Image Binarization Technique for Degraded Document Images)
- Co-prime Array
- 遍历二叉树的各种操作
- 常用的Java资源整理, 还是比较全的。