从1 到 n 中1出现的次数
求出1~13
的整数中1出现的次数,并算出100~1300
的整数中1出现的次数?为此他特别数了一下1~13
中包含1的数字有1、10、11、12、13
因此共出现6
次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数)。
class Solution {
public:
int NumberOf1Between1AndN_Solution(int n)
{
int ret = 0;
for (int i = 1; i <= n; i++)
{
int num = i;
while (num)
{
if (num % 10 == 1)
ret++;
num = num / 10;
}
}
return ret;
}
};
把数组排成最小的数
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
解题思路: 先将整型数组转换成String数组,然后将String数组排序,最后将排好序的字符串数组拼接出来。关键就是制定排序规则。
- 排序规则如下,
假如有元素a和元素b,若ab > ba 则 a应该处于b之后;若ab < ba 则a应该处于b之前;若ab = ba 则 a = b;解释说明:比如 “3” 和 "31"比较谁先谁后, “331” > “313”,‘31’应该处于‘3’之前。
class Solution {
public:
string PrintMinNumber(vector<int> numbers) {
string res ="";
sort(numbers.begin(),numbers.end(),cmp);
for(int i=0;i<numbers.size();i++){
res += to_string(numbers[i]);
}
return res;
}
static bool cmp(int a,int b){
string sa = "";
string sb = "";
sa += to_string(a);
sa += to_string(b);
sb += to_string(b);
sb += to_string(a);
return sa<sb;
}
};
丑数
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
思路
我们规定了只包含质因子2,3,5的是丑数,也就是说,一个数可以由有限个2 和有限个3 和有限个5相乘的来,换言之,这个数可以最后分解成 n 1 n1 n1个2, n 2 n2 n2个3, n 3 n3 n3个5组成,我们还知道 1 是最小的丑数。那么如何从1推出下一个丑数呢。我们在列举几个丑数观察。
1 , 1*2, 1*3, 2*2, 1*5, 2*3 ,3*2,4*2, 3*3 ...
我们发现每个数,都可以由前面某个数 ×2 或者 ×3 或者 ×5得到,即这些数按升序插入到这个数组。
代码实现:
class Solution {
public:
int GetMin(int a,int b,int c)
{
if(a < b)
return a < c ? a : c;
else
return b < c ? b : c;
}
int GetUglyNumber_Solution(int index) {
if(index < 0)
return -1;
int pos2 = 1,pos3 = 1,pos5 = 1;
int* arr = new int[index + 1];
arr[1] = 1;
for(int i=2;i <= index;i++)
{
arr[i] = GetMin(arr[pos2]*2,arr[pos3]*3,arr[pos5]*5);
if(arr[pos2]*2 <= arr[i])
pos2++;
if(arr[pos3]*3 <= arr[i])
pos3++;
if(arr[pos5]*5 <= arr[i])
pos5++;
}
return arr[index];
}
};