387. First Unique Character in a String
Given a string, find the first non-repeating character in it and return it’s index. If it doesn’t exist, return -1.
Examples:
s = "leetcode"
return 0.
s = "loveleetcode",
return 2.
Note: You may assume the string contain only lowercase letters.
Solution in C++:
关键点:
- 第一个非重复字符
思路:
- 因为是字母所以就很有限了,大概思想是先扫描一遍string s,记录其中的字母个数,然后再扫描一遍记录判断其是否大小为1,是即为第一个非重复字符的下标。
int firstUniqChar(string s) {
map<char, int> maps;
for(auto ch : s){
map<char, int>::iterator it = maps.find(ch);
if (it != maps.end()){
++maps[ch];
} else{
maps[ch] = 1;
}
}
size_t size = s.size();
for(int i = 0; i < size; ++i)
if(maps[s[i]] == 1)
return i;
return -1;
}
389. Find the Difference
Given two strings s and t which consist of only lowercase letters.
String t is generated by random shuffling string s and then add one more letter at a random position.
Find the letter that was added in t.
Example:
Input:
s = "abcd"
t = "abcde"
Output:
e
Explanation:
'e' is the letter that was added.
Solution in C++:
关键点:
- 多余字母
思路:
- 实际就是找另一个字符串中多出来的那个字母,我感觉我现在做这类题目已经有种惯性了,直接就是先扫描string s,记录其中每个字母的个数。然后再扫描一遍string t,将记录中对应字母个数-1,再判断是否小于0,是则找到了;
- 然后看到了discuss里面的一个答案,让我又想起了XOR的用法,就是获取到奇数个个数的东西。
方法一:暴力扫描
char findTheDifference(string s, string t) {
vector<int> characters(26,0);
for(auto ch : s){
++characters[ch-'a'];
}
for(auto ch : t){
if (characters[ch-'a'] == 0)
return ch;
else{
if (--characters[ch-'a'] < 0)
return ch;
}
}
}
方法二:XOR
char findTheDifference(string s, string t) {
char res = 0;
for(auto ch : s)
res ^= ch;
for(auto ch : t)
res ^= ch;
return res;
}
400. Nth Digit
Find the
n
t
h
n^{th}
nth digit of the infinite integer sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, …
Note:
n is positive and will fit within the range of a 32-bit signed integer (n <
2
31
2^{31}
231).
Example 1:
Input:
3
Output:
3
Example 2:
Input:
11
Output:
0
Explanation:
The 11th digit of the sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... is a 0, which is part of the number 10.
Solution in C++:
关键点:
- 哈哈哈
思路:
- 用一个数组存i位数字的第一个数字,然后用另外一个数组存i位数字的总位数。这两个数组需要自己初始化,因为范围是int所以这两个数组的大小并不大。基本算法大家自己列举几个就看出来规律了。然后根据输入的n判断属于哪个位数段,再计算出数字加偏移即可得出数字。看了下大家大致的思想都差不多,对于处理得到num[offset]有的直接转换成字符串得到,我的方法可能朴素了点,就直接是数字方法获取,所以自己写了获取num的offset位的方法。
位数 | 第一个数字 | 总个数 | 总位数 |
---|---|---|---|
i | 1 0 i − 1 10^{i-1} 10i−1 | 9 * 1 0 i − 1 10^{i-1} 10i−1 | 9 * 1 0 i − 1 10^{i-1} 10i−1 * i |
class Solution {
public:
int getDigit(int num, int index, int totalDigit){
if (index > totalDigit)
return -1;
int i = totalDigit - index;
int count = 0;
while(num){
if (count == i)
return num % 10;
num /= 10;
++count;
}
}
int findNthDigit(int n) {
// startNum[i] 表示当数字位数为i时第一个数 eg.startNum[1] = 1
vector<int> startNum{0};
// totalDigit[i] 表示当数字位数为i时总位数 eg.totalDigit[1] = 9
vector<long long> totalDigit{0};
long long sumDigit = 9;
long long num = 1;
for(int i = 1; num < INT_MAX; ++i){
startNum.push_back(num);
totalDigit.push_back(sumDigit);
sumDigit = 9 * pow(10,i) * (i+1);
num = pow(10,i);
}
size_t size = totalDigit.size();
for(int i = 1; i < size; ++i){
long long tmp = n - totalDigit[i];
if (tmp <= 0){
int index = n / i; // 第几个数
int offset = n % i; // 数字中第几位
// 计算数字
num = startNum[i] + index;
if (i == 1)
--num;
if (offset == 0){
if (i == 1)
return num;
return getDigit(num-1,i,i);
} else{
return getDigit(num,offset,i);
}
}
n -= totalDigit[i];
}
}
};
小结
今天前面两题基本没花什么大时间,主要最后一题的逻辑处理部分花了不少时间,对于index的处理以及offset的处理。然后再就是long long越界问题的处理。然后对于XOR的方法有加深了印象。
知识点
- XOR求奇数个数的问题