非科班选手的刷题打卡记录Day1

第一天写博客,有点紧张~主要想记录自己平时刷的题、学到的知识点和思路心得。

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值