题目链接
class Solution {
public:
string destCity(vector<vector<string>>& p) {
int n = p.size();
unordered_map<string,int> mp;
for (int i = 0; i < n; i ++){
mp[p[i][0]]++;
if(mp[p[i][1]] == 1)continue;
mp[p[i][1]] = 0;
}
for (auto it = mp.begin(); it != mp.end(); it ++){
if (it->second == 0){
return it->first;
}
}
return "";
}
};
题目链接
32位二进制可以表示8位16进制数
原码 + 取反 + 1 = 补码
补码 + 取反 + 1 = 原码
class Solution {
public:
string toHex(int num) {
if (num == 0) return "0";
string sb;
for (int i = 7; i >= 0; i --) {
int val = (num >> (4 * i)) & 0xf; //一次取4位进行比较
if (sb.length() > 0 || val > 0) { //去除前导零
char digit = val < 10 ? (char) ('0' + val) : (char) ('a' + val - 10);
sb.push_back(digit);
}
}
return sb;
}
};
题目链接
借鉴小爱
typedef long long ll;
class Solution {
public:
string fractionToDecimal(int numerator, int denominator) {
ll n = numerator, d = denominator;
string res = "";
// 计算整数部分
// 判断负数
if(n * d < 0) res += "-";
ll a = n / d;
if(a < 0) a *= -1;
res += to_string(a);
if(n < 0) n *= -1;
if(d < 0) d *= -1;
// 计算小数部分
n %= d;
if(n == 0) return res; // 无小数
res += ".";
// 连除
// 哈希表记录是否有数组第二次出现
unordered_map<int, int> st;
string t = "";
int index = 0;
while(n && !st.count(n)) {
st[n] = index++;
n *= 10;
t += to_string(n/d);
n %= d;
}
if(n != 0) {
// 说明出现了循环,此时对循环部分 [st[n], index] 加括号
res += t.substr(0, st[n]) + "(" + t.substr(st[n]) + ")";
} else res += t;
return res;
}
};
题目链接
class Solution {
public:
string licenseKeyFormatting(string s, int k) {
int n = s.size(),num = 0;
string st;
for (int i = 0; i < n; i ++){
if (s[i] != '-'){
num ++;
if ('a' <= s[i] && s[i] <= 'z')st.push_back(s[i] - 32);
else st.push_back(s[i]);
}
}
string res = "";
n = st.size();
for (int i = n - 1,j = 1; i >= 0; i --,j ++){
res += st[i];
if (j % k == 0 && j != n)res += '-';
}
reverse(res.begin(),res.end());
return res;
}
};
class PeekingIterator : public Iterator {
public:
PeekingIterator(const vector<int>& nums) : Iterator(nums) {
flag = Iterator::hasNext();
if (flag) {
nextElement = Iterator::next();
}
}
int peek() {
return nextElement;
}
int next() {
int ret = nextElement;
flag = Iterator::hasNext();
if (flag) {
nextElement = Iterator::next();
}
return ret;
}
bool hasNext() const {
return flag;
}
private:
int nextElement;
bool flag;
};
题目链接
class Solution {
public:
int thirdMax(vector<int>& n) {
sort(n.begin(),n.end());
n.erase(unique(n.begin(),n.end()),n.end());
int le = n.size();
if (le < 3)return n[le-1];
return n[le-3];
}
};
题目链接
一 定 要 读 好 题 目 每 个 字 一定要读好题目每个字 一定要读好题目每个字
class Solution {
public:
int countSegments(string s) {
int res = 0;
for (int i = 0; i < s.size(); i++)
if ((i == 0 || s[i - 1] == ' ') && s[i] != ' ')
res++;
return res;
}
};
题目链接
class Solution {
public:
vector<string> findRepeatedDnaSequences(string s) {
vector<string> res;
int n = s.size();
if (n <= 10)return res;
map<string,int> mp;
string st = "";
int i = 0;
for (; i < 10; i ++)st+=s[i];
mp[st] ++;
for (; i < n; i ++){
st = st.substr(1,10) + s[i];
mp[st] ++;
if (mp[st] == 2)res.push_back(st);
}
return res;
}
};
题目链接 官方题解
看 官 方 题 解 + 下 面 代 码 注 释 看官方题解+下面代码注释 看官方题解+下面代码注释
class SummaryRanges {
private:
map<int, int> mp;
public:
SummaryRanges() {}
void addNum(int val) {
auto l1 = mp.upper_bound(val);//查找第一个大于val的位置,不存在时返回mp.end();说明这个val比之前所有的数都大
auto l0 = (l1 == mp.begin() ? mp.end() : prev(l1));//如果l1等于mp.begin()那么说明这个数比所有的数都小,然后将l0 = mp.end(),否者l0 = pre(l1);
if (l0 != mp.end() && l0->first <= val && val <= l0->second){
// 情况一
return;
}else {
//判断是否靠近左边界
bool left_aside = (l0 != mp.end() && l0->second + 1 == val);
//判断是否靠近有边界
bool right_aside = (l1 != mp.end() && l1->first - 1 == val);
if (left_aside && right_aside) {
// 情况四
int left = l0->first, right = l1->second;
mp.erase(l0);
mp.erase(l1);
mp.emplace(left, right);
} else if (left_aside) {
// 情况二
++l0->second;
} else if (right_aside) {
// 情况三
int right = l1->second;
mp.erase(l1);
mp.emplace(val, right);
} else {
// 情况五
mp.emplace(val, val);
}
}
}
vector<vector<int>> getIntervals() {
vector<vector<int>> ans;
for (const auto& [left, right]: mp) {
ans.push_back({left, right});
}
return ans;
}
};
题目链接
class Solution {
public:
int arrangeCoins(int n) {
int l = 1,r = 2 << 16 + 10;
while(l < r){
long long mid = l + r + 1 >> 1;
if (mid * (mid + 1) / 2 <= n)l = mid;
else r = mid - 1;
}
return l;
}
};
题目链接
题意:一个整数翻译成英文数字
挺 有 意 思 的 挺有意思的 挺有意思的
class Solution {
public:
vector<string> singles = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"};
vector<string> teens = {"Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
vector<string> tens = {"", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
vector<string> thousands = {"", "Thousand", "Million", "Billion"};
string numberToWords(int num) {
if (num == 0) return "Zero";
string sb;
for (int i = 3, unit = 1000000000; i >= 0; i--, unit /= 1000) {
int curNum = num / unit;
if (curNum != 0) {
num -= curNum * unit;
string curr;
recursion(curr, curNum);
curr = curr + thousands[i] + " ";
sb = sb + curr;
}
}
while (sb.back() == ' ') {
sb.pop_back();
}
return sb;
}
void recursion(string & curr, int num) {
if (num == 0) {
return;
} else if (num < 10) {
curr = curr + singles[num] + " ";
} else if (num < 20) {
curr = curr + teens[num - 10] + " ";
} else if (num < 100) {
curr = curr + tens[num / 10] + " ";
recursion(curr, num % 10);
} else {
curr = curr + singles[num / 100] + " Hundred ";
recursion(curr, num % 100);
}
}
};
题目链接
class Solution {
public:
int divide(int dividend, int divisor) {
// 考虑被除数为最小值的情况
if (dividend == INT_MIN) {
if (divisor == 1) return INT_MIN;
if (divisor == -1) return INT_MAX;
}
// 考虑除数为最小值的情况
if (divisor == INT_MIN) return dividend == INT_MIN ? 1 : 0;
// 考虑被除数为 0 的情况
if (dividend == 0) return 0;
// 一般情况,使用二分查找
// 将所有的正数取相反数,这样就只需要考虑一种情况
bool rev = false;
if (dividend > 0) {
dividend = -dividend;
rev = !rev;
}
if (divisor > 0) {
divisor = -divisor;
rev = !rev;
}
// 快速乘
auto quickAdd = [](int y, int z, int x) {
// x 和 y 是负数,z 是正数
// 需要判断 z * y >= x 是否成立
int result = 0, add = y;
while (z) {
if (z & 1) {
// 需要保证 result + add >= x
if (result < x - add) {
return false;
}
result += add;
}
if (z != 1) {
// 需要保证 add + add >= x
if (add < x - add) {
return false;
}
add += add;
}
// 不能使用除法
z >>= 1;
}
return true;
};
int left = 1, right = INT_MAX, ans = 0;
while (left <= right) {
// 注意溢出,并且不能使用除法
int mid = left + ((right - left) >> 1);
bool check = quickAdd(divisor, mid, dividend);
if (check) {
ans = mid;
// 注意溢出
if (mid == INT_MAX) break;
left = mid + 1;
}else right = mid - 1;
}
return rev ? -ans : ans;
}
};
题目链接
class Solution {
public:
vector<string> fizzBuzz(int n) {
vector<string> res;
for (int i = 1; i <= n; i ++){
if (i % 3 == 0 && i % 5 == 0)res.push_back("FizzBuzz");
else if (i % 3 == 0) res.push_back("Fizz");
else if (i % 5 == 0) res.push_back("Buzz");
else res.push_back(""+to_string(i));
}
return res;
}
};
class Solution {
public:
int peakIndexInMountainArray(vector<int>& arr) {
int n = arr.size();
int l = 1,r = n;
while(l < r){
int mid = l + r >> 1;
if (arr[mid] > arr[mid + 1])r = mid;
else l = mid + 1;
}
return l;
}
};
题目链接
class Solution {
public:
string countAndSay(int n) {
string res = "1";
for (int i = 2; i <= n; i ++) {
string st = "";
int l = 0,r = 0,le = res.size();
while (r < le) {
while (r < le && res[r] == res[l]) r ++;
st += to_string(r - l) + res[l];
l = r;
}
res = st;
}
return res;
}
};
非 常 值 得 回 味 的 一 道 题 非常值得回味的一道题 非常值得回味的一道题
题目链接
typedef long long ll;
class Solution {
public:
string num;
vector<string> res;
int n, target;
void dfs(string s, int index, ll ans, ll mul) {
if (index == n) {
if (ans == target) res.push_back(s);
return;
}
// 当前表达式长度
int m = s.size();
if (index > 0) s.push_back(0); // 占位(扩充一个位子),方便下面填充符号
ll val = 0;
// 枚举截取的数字长度(取多少位),注意数字可以是单个0但不能有前导零
for (int j = index; j < n && (j == index || num[index] != '0'); j ++) {
val = val * 10 + num[j] - '0';
s.push_back(num[j]);
if (index == 0) { // 表达式开头不能添加符号
dfs(s, j + 1, val, val);
} else {
s[m] = '+';
dfs(s, j + 1, ans + val, val);
s[m] = '-';
dfs(s, j + 1, ans - val, -val);
s[m] = '*';
dfs(s, j + 1, ans - mul + mul * val, mul * val);
}
}
};
vector<string> addOperators(string _num, int _target) {
num = _num;
n = _num.length();
target = _target;
string s;
dfs(s, 0, 0, 0);
return res;
}
};
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int res;
int dfs(TreeNode* root,int k){
if (root == nullptr)return 0;
int l = dfs(root->left,k);
if (l + 1 == k) res = root->val;
int r = dfs(root->right,k-l-1);
return l + r + 1;
}
int kthSmallest(TreeNode* root, int k) {
dfs(root,k);
return res;
}
};
题目链接
struct TrieNode{
vector<TrieNode *> child;
bool isEnd;
TrieNode() {
this->child = vector<TrieNode *>(26,nullptr);
this->isEnd = false;
}
};
void insert(TrieNode * root, const string & word) {
TrieNode * node = root;
for (auto c : word) {
if (node->child[c - 'a'] == nullptr) {
node->child[c - 'a'] = new TrieNode();
}
node = node->child[c - 'a'];
}
node->isEnd = true;
}
class WordDictionary {
public:
WordDictionary() {
trie = new TrieNode();
}
void addWord(string word) {
insert(trie,word);
}
bool search(string word) {
return dfs(word, 0, trie);
}
bool dfs(const string & word,int index,TrieNode * node) {
if (index == word.size()) {
return node->isEnd;
}
char ch = word[index];
if (ch >= 'a' && ch <= 'z') {
TrieNode * child = node->child[ch - 'a'];
if (child != nullptr && dfs(word, index + 1, child)) {
return true;
}
} else if (ch == '.') {
for (int i = 0; i < 26; i++) {
TrieNode * child = node->child[i];
if (child != nullptr && dfs(word, index + 1, child)) {
return true;
}
}
}
return false;
}
private:
TrieNode * trie;
};
转换思维
把n-1个增大,就是把那一个减小
题目链接
class Solution {
public:
int minMoves(vector<int>& nums) {
int res = 0,mi = 9999999999,n = nums.size();
for (int i = 0; i < n; i ++)mi = min(mi,nums[i]);
for (int i = 0; i < n; i ++)res += nums[i] - mi;
return res;
}
};
题目链接
class Solution {
public:
vector<int> plusOne(vector<int>& d) {
int tmp = 1,n = d.size();
for (int i = n - 1; i >= 0; i --){
if (d[i] + tmp >= 10){
d[i] = (d[i] + tmp)%10;
tmp = 1;
}else {
d[i] = d[i] + tmp;
tmp = 0;
break;
}
}
if (tmp)d.insert(d.begin(),1);
return d;
}
};
题意:给定一个大小为 n 的整数数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。
进阶:尝试设计时间复杂度为 O(n)、空间复杂度为 O(1)的算法解决此问题。
普通写法
就直接哈希
class Solution {
public:
vector<int> majorityElement(vector<int>& nums) {
int n = nums.size();
vector<int> ans;
unordered_map<int, int> cnt;
for (auto & v : nums) cnt[v]++;
for (auto & v : cnt)
if (v.second > n / 3)
ans.push_back(v.first);
return ans;
}
};
进阶写法
因为数量大于等于n/3的数最多有两个。
class Solution {
public:
vector<int> majorityElement(vector<int>& nums) {
vector<int> ans;
int element1 = 0,element2 = 0,vote1 = 0,vote2 = 0;
for (auto & num : nums) {
if (vote1 > 0 && num == element1) { //如果该元素为第一个元素,则计数加1
vote1++;
} else if (vote2 > 0 && num == element2) { //如果该元素为第二个元素,则计数加1
vote2++;
} else if (vote1 == 0) { // 选择第一个元素
element1 = num;
vote1++;
} else if (vote2 == 0) { // 选择第二个元素
element2 = num;
vote2++;
} else { //如果三个元素均不相同,则相互抵消1次
vote1--;
vote2--;
}
}
//到这里只能说明这两个数最有可能是大于等于n/3的两个元素,还需要在遍历一次确认
int cnt1 = 0,cnt2 = 0;
for (auto & num : nums) {
if (vote1 > 0 && num == element1) cnt1++;
if (vote2 > 0 && num == element2) cnt2++;
}
// 检测元素出现的次数是否满足要求
if (vote1 > 0 && cnt1 > nums.size() / 3) ans.push_back(element1);
if (vote2 > 0 && cnt2 > nums.size() / 3) ans.push_back(element2);
return ans;
}
};
题目链接
class Solution {
public:
vector<int> constructRectangle(int a) {
int t = sqrt(a);
vector<int> res;
for (int i = t; i >= 1; i --){
if (a % i == 0){
res.push_back(i);
res.push_back(a / i);
break;
}
}
sort(res.begin(),res.end());
reverse(res.begin(),res.end());
return res;
}
};