第一题:整数中1出现的次数
题目:
求出1 ~ 13的整数中1出现的次数,并算出100 ~ 1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数。
解析:
class Solution {
public:
int NumberOf1Between1AndN_Solution(int n)
{
int ret = 0;
for (int power = 1, high = n / 10, low = 0, cur = n % 10; n / power;
ret += high * power + (cur == 0 ? 0 : cur == 1 ? low + 1 : power),
power *= 10, high = n / power / 10, cur = n / power % 10, low = n % power);
return ret;
}
};
第二题:把数组排成最小的数
题目:
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
解析:
class Solution {
public:
string PrintMinNumber(vector<int> numbers) {
vector<string> req;
for (int i = 0; i < (int)numbers.size(); i++) {
req.push_back(to_string(numbers[i]));
}
sort(req.begin(), req.end(), cmp);
string res;
for (int i = 0; i < (int)req.size(); i++) {
res += req[i];
}
return res;
}
static bool cmp(const string& A, const string& B)
{
return A + B < B + A;
}
};
学习1:注意sort中的比较函数的写法
第三题:丑数
题目:
把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
解析:
class Solution {
public:
int GetUglyNumber_Solution(int index) {
vector<int> res;
res.push_back(1);
for (int i = 1; i < index; i++) {
int last = 0x3f3f3f3f;
for (int j = 0; j < i; j++) {
if (res[j] * 2 > res[i-1]) {
last = last > res[j] * 2 ? res[j] * 2 : last;
break;
}
}
for (int j = 0; j < i; j++) {
if (res[j] * 3 > res[i-1]) {
last = last > res[j] * 3 ? res[j] * 3 : last;
break;
}
}
for (int j = 0; j < i; j++) {
if (res[j] * 5 > res[i-1]) {
last = last > res[j] * 5 ? res[j] * 5 : last;
break;
}
}
res.push_back(last);
}
return res[index - 1];
}
};
第四题:第一个只出现一次的字符位置
题目:
在一个字符串(
1<=字符串长度<=10000
,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置
解析:
先用
map
把对应字符和出现的次数映射起来,然后从头开始查找,找到第一个只出现一次的字符返回就好了。
class Solution {
public:
int FirstNotRepeatingChar(string str) {
map<char, int> pmap;
for (int i = 0; i < str.length(); i++) {
pmap[str[i]]++;
}
for (int i = 0; i < str.length(); i++) {
if (pmap[str[i]] == 1) return i;
}
return -1;
}
};
第五题:数组中的逆序对
题目:
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007。
解析:
class Solution {
public:
int InversePairs(vector<int> data) {
return (int)dfs(data, 0, data.size());
}
long long dfs(vector<int> &data, int l, int r) {
if (r - l == 1)
return 0;
const long long mod = 1000000007;
int mid = (l + r) >> 1, ret = (dfs(data, l, mid) % mod + dfs(data, mid, r) % mod) % mod;
vector<int> arr;
int p_l = l, p_r = mid;
for (; p_l < mid && p_r < r; )
if (data[p_l] > data[p_r])
arr.push_back(data[p_r++]), ret = (ret + mid - p_l) % mod;
else
arr.push_back(data[p_l++]);
for (; p_l < mid; arr.push_back(data[p_l++]));
for (; p_r < r; arr.push_back(data[p_r++]));
for (int i = 0; l < r; data[l++] = arr[i++]);
return ret % mod;
}
};
第六题:两个链表的第一个公共结点
题目:
输入两个链表,找出它们的第一个公共结点。
解析:
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
class Solution {
public:
ListNode* FindFirstCommonNode(ListNode* pHead1, ListNode* pHead2) {
auto cur1 = pHead1;
auto cur2 = pHead2;
while (!(cur1 == cur2))
{
cur1 = cur1 == nullptr ? pHead1 : cur1->next;
cur2 = cur2 == nullptr ? pHead2 : cur2->next;
}
return cur1;
}
};