概述
第一天写博客,有点紧张~主要想记录自己平时刷的题、学到的知识点和思路心得。
1. 每日一题
386. 字典序排数
难度中等352
给你一个整数 n
,按字典序返回范围 [1, n]
内所有整数。
你必须设计一个时间复杂度为 O(n)
且使用 O(1)
额外空间的算法。
示例 1:
输入:n = 13 输出:[1,10,11,12,13,2,3,4,5,6,7,8,9]
示例 2:
输入:n = 2 输出:[1,2]
提示:
1 <= n <= 5 * 104
class Solution {
public:
vector<int> lexicalOrder(int n) {
vector<int> ret(n);//返回值不计入空间复杂度
int temp = 1;//ret[i],初始值为1
for(int i = 0; i < n; i++){
ret[i] = temp;
if(temp * 10 <= n){//如果不越界,先在下一位加个0
temp *= 10;
}
else{
if(temp >= n){//越界,说明末位搜索完毕
temp /= 10;//回到上一位
}
temp++;
while(temp % 10 == 0){//末位为0//e.g.199->2
temp /= 10;
}
}
}
return ret;
}
};
遍历1-n的每个数,在不超过n的情况下先在当前数后面加个0作为下一个数,然后依次+1直到>=n,说明最后一位已经搜索完毕,/10回到上一位,+1直到末位为0再返回上一位。
2.两数之和
剑指 Offer 57. 和为s的两个数字
输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。
示例 1:
输入:nums = [2,7,11,15], target = 9 输出:[2,7] 或者 [7,2]
示例 2:
输入:nums = [10,26,30,31,47,60], target = 40 输出:[10,30] 或者 [30,10]
限制:
1 <= nums.length <= 10^5
1 <= nums[i] <= 10^6
咱一看这不是梦开始的地方吗!当时我还是一个连哈希都不懂的小白。立刻重拳出击一下:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_set<int> numSet;
for(int num : nums){
if(numSet.count(target - num)){
return {num,target - num};
}
numSet.insert(num);
}
return {};
}
};
再看这题是排序数组,因此双指针效率更高:(时间复杂度O(N),空间复杂度O(1))再次重拳出击:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
int left = 0, right = nums.size() - 1;
while(left < right){
if(nums[left] + nums[right] == target){
return {nums[left],nums[right]};
}
if(nums[left] + nums[right] > target){
right--;
}
else{
left++;
}
}
return {};
}
};
3.
剑指 Offer 57 - II. 和为s的连续正数序列
输入一个正整数 target
,输出所有和为 target
的连续正整数序列(至少含有两个数)。
序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。
示例 1:
输入:target = 9 输出:[[2,3,4],[4,5]]
示例 2:
输入:target = 15 输出:[[1,2,3,4,5],[4,5,6],[7,8]]
限制:
1 <= target <= 10^5
一开始没看到连续,上来就是一个回溯...
看到标签有双指针,想到可以用两个变量表示当前的起点和终点,初始为1,如果当前序列的和还不到给定值,继续向右移动终点,如果超过给定值则向右移动起点,如果和给定值相等则记录当前的序列。
class Solution {
public:
vector<vector<int>> findContinuousSequence(int target) {
if(target == 1) return {{1}};
vector<vector<int>> ret;
int left = 1,right = 1;//序列的起点和终点
int sum = 0;
while(left <= target / 2){//起点只可能在前一半数
if(sum < target){//不到目标值,说明该起点还未搜索完,后移终点
sum += right;
right++;
}
else if(sum > target){//超过目标值,说明该起点已搜索完,应该向后移起点
sum -= left;
left++;
}
else if(sum == target){
vector<int> temp;
for(int i = left; i < right; i++){
temp.push_back(i);
}
ret.push_back(temp);
sum -= left;
left++;
}
}
return ret;
}
};
总结:今天大部分时间用于给带的本科生学弟写代码..头秃,明天继续,还差得远呢TT
最后
以上就是幸福蜜粉为你收集整理的非科班选手的刷题打卡记录Day1的全部内容,希望文章能够帮你解决非科班选手的刷题打卡记录Day1所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复