今天本来要整顿一下MySQL的收藏夹,但是发现阿骨朵挺好玩的,于是。。嗯
我果断调整方向,刷上几题。
刚开始都顺风顺水的,直到第四题,那个 “中等题”。。。
给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的 绝对值 至多为 k。
示例 1:
输入: nums = [1,2,3,1], k = 3
输出: true
示例 2:
输入: nums = [1,0,1,1], k = 1
输出: true
示例 3:
输入: nums = [1,2,3,1,2,3], k = 2
输出: false
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/contains-duplicate-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
这题,需要说吗?首先有个K的限制,很明确的告诉我们要用滑动窗口。
其次,比对已存在的值,怎么比对?轮询嘛。难不成还有更快的?
当然有啊,哈希表嘛。
然后,就完了嘛。
bool containsNearbyDuplicate(vector<int>& nums, int k) {
unordered_set<int> existed;
int n = nums.size();
int curr = 0;
for (int i = 0; i < n; ++i){
curr = nums[i];
if (existed.find(curr) == existed.end()){
existed.insert(curr);
if (existed.size() > k)
existed.erase(nums[i-k]);
}
else
return true;
}
return false;
}
给定一个大小为 n 的整数数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。
进阶:尝试设计时间复杂度为 O(n)、空间复杂度为 O(1)的算法解决此问题。
示例 1:
输入:[3,2,3]
输出:[3]
示例 2:
输入:nums = [1]
输出:[1]
示例 3:
输入:[1,1,1,3,3,2,2,2]
输出:[1,2]
提示:
1 <= nums.length <= 5 * 10^4
-10^9 <= nums[i] <= 10^9
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/majority-element-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
怎么搞?我能想到的就,答案最多只有两个数嘛,然后呢?这个线索好像并没有什么帮助。
那就老老实实的遍历、计数嘛。
我看有种解法教做摩尔取值法,找出最有希望的答案。我还是喜欢老老实实去遍历,安全。
vector<int> majorityElement(vector<int>& nums) {
if (nums.empty()) {
return {
};
}
vector<int> res;
int N = nums.size();
unordered_map<int, int> mp;
for (const auto& num : nums) {
mp[num]++;
}
for (const auto& m : mp) {
if (m.second > N / 3) {
res.push_back(m.first);
}
}
return res;
}
编写一个程序判断给定的数是否为丑数。
丑数就是只包含质因数 2, 3, 5 的正整数。
真的是简单到不能再简单了,就不讲了。
那为什么我要放这题出来?我是个极简主义者,太简单的题目我做了就当没做过。
这题不一样,这题简单的很,但是丫的进化版让我想了很久。。。
找出第n个丑数。
注:
好,现在怎么看?
这玩意儿有规律吗?有没有规律,列举一下就知道了:
1,2,3,4,5,6,8,9,10,12,15,16,18,20····
找个规律我看看啊。
找不出来的话,那就只能老老实实从头枚举到n了。
那要怎么枚举?土办法我实在是不想再想了,又烧脑又没用。
这里讲个大家都在用的三指针法。
首选,来三个指针,分别指向 2,3,5。来一个列表,纪录走过的路。
开局,三个指针都指向1.
三个指针分别乘与自己指向的位置,然后,比对一下哪个小,小的那个就插进列表尾巴去。并把那个指针往前走。
如果遇上相等的,那就把那俩指针都往前一步。
别给我扯万一三个指针乘起来都相等,找一个出来呗。
重复上述步骤。
就这样,挪到列表长度为n之后,返回列表[n-1]。
抽象,别钻牛角尖,拿张纸画一遍过去就通了。
class Solution {
public:
int nthUglyNumber(int n) {
if (n <= 0) {
return 0;
}
int i = 0, j = 0, k = 0; //三指针
vector<int> ret; //存储
ret.push_back(1); //初始哈第一个位置
int sz = 1; //ret的长度
for (;sz < n;) {
if (ret[i] * 2 <= ret[j] * 3 && ret[i] * 2 <= ret[k] * 5) {
//如果出现相等
if (ret[i] * 2 == ret[j] * 3)
j++;
else if (ret[i] * 2 == ret[k] * 5)
k++;
else {
//选取2
ret.push_back(ret[i] * 2);
i++;
sz++;
}
}
else if (ret[j] * 3 <= ret[i] * 2 && ret[j] * 3 <= ret[k] * 5) {
//如果出现相等
if (ret[i] * 2 == ret[j] * 3)
i++;
else if (ret[j] * 3 == ret[k] * 5)
k++;
else {
//选取3
ret.push_back(ret[j] * 3);
j++;
sz++;
}
}
else if (ret[k] * 5 <= ret[i] * 2 && ret[k] * 5 <= ret[j] * 3) {
//如果出现相等
if (ret[k] * 5 == ret[j] * 3)
j++;
else if (ret[i] * 2 == ret[k] * 5)
i++;
else {
//选取5
ret.push_back(ret[k] * 5);
k++;
sz++;
}
}
}
return ret[n-1];
}
};
class Solution {
public:
int nthUglyNumber(int n) {
int n2(0), n3(0), n5(0);
int *dp = new int[n];
dp[0] = 1;
for(int i = 1; i < n; ++i){
int next2 = dp[n2]*2, next3 = dp[n3]*3, next5 = dp[n5]*5;
if(next2 <= next3 && next2 <= next5){
dp[i] = next2;
n2++;
}
if(next3 <= next2 && next3 <= next5){
dp[i] = next3;
n3++;
}
if(next5 <= next2 && next5 <= next3){
dp[i] = next5;
n5++;
}
}
return dp[n-1];
}
};
这就是我和大佬的差距。