力扣题目训练(3)

2024年1月27日力扣题目训练

2024年1月27日第三天编程训练,今天主要是进行一些题训练,包括简单题3道、中等题2道和困难题1道,昨天没有做完,自制力还是不行,我写这个的初衷只是为了记录自己每天干了什么,希望能坚持下去。

290. 单词规律

链接: 丑数
难度: 简单
题目:题目描述
运行示例:
运行示例
思路:
由题目可知,这是一个映射关系,可以利用哈希表来做,但是只用一个哈希表无法完成双向绑定的效果故需要利用两个哈希表。
代码:

class Solution {
public:
    bool wordPattern(string pattern, string s) {
        unordered_map<char,string> map;
        unordered_map<string,char> rmap;
        vector<string> vtr;
        int t =-1;
        for(int i = 0 ; i < s.size(); i++){
           if(s[i] == ' '){
               t += 1;
               vtr.push_back(s.substr(t,i-t));
               t = i;
           }
        }
        vtr.push_back(s.substr(t+1,s.size()-1));
        int n = pattern.size();
        int m = vtr.size();
        if(m != n) return false;
        for(int i = 0; i < n; i++){
            map[pattern[i]] = vtr[i];
            rmap[vtr[i]] = pattern[i];
        }
        for(int i = 0; i < n; i++){
            if( map[pattern[i]] != vtr[i] || pattern[i] != rmap[vtr[i]]) return false;
        }
        return true;
    }
};

292. Nim 游戏

链接: 游戏
难度: 简单
题目:
题目描述
运行示例:
运行示例

思路:
数学问题,当自己面对4块石头时,无论怎样都无法胜出,故需避免总的石头数目为 4 的倍数。
代码:

class Solution {
public:
    bool canWinNim(int n) {
        return n%4 != 0;
    }
};

303. 区域和检索 - 数组不可变

链接: 区域和检索
难度: 简单
题目:
题目描述
运行示例:
运行示例

思路:
这道题目如果单纯的用循环相加也能做,但是很有可能时间超过,所以我采用的是求前项和,要求指定区间内的和可以相减即可。
代码:

class NumArray {
public:
    vector<int> sums;
    NumArray(vector<int>& nums) {
        sums.push_back(nums[0]);
        for(int i = 1; i < nums.size(); i++){
            sums.push_back(sums[i-1]+nums[i]);
        }

    }
    
    int sumRange(int left, int right) {
        if(left == 0) return sums[right];
        return sums[right]-sums[left-1];
    }
};

91. 解码方法

链接: 解码
难度: 中等
题目:
题目描述
运行示例:
运行示例

思路:
我是用递归做的,结果时间超过了。我看了解析是用动态规划做的,原因是当前字母的解码方法可以看做前面的解码方方法加上这个字母的解码方法。f[i]可以看作字符串 s的前 i个字符 s[1…i]s[1…i]s[1…i] 的解码方法数。
代码:

class Solution {
public:
    int numDecodings(string s) {
        int n = s.size();
        vector<int> f(n+1);
        f[0] = 1;
        for(int i = 1; i <= n; i++){
            if(s[i-1] != '0'){
                f[i] += f[i-1];
            }
            if(i > 1 && s[i - 2] != '0' && ((s[i - 2] - '0') * 10 + (s[i - 1] - '0') <= 26)  ){
                f[i] += f[i-2];
            }
        }
        return f[n];
    }
};

92. 反转链表 II

链接: 反转链表
难度: 中等
题目:
题目描述
运行示例:
运行示例
思路:
一次遍历的话就用头插法进行实现,注意给的head是不带头指针的,所以为了方便起见可以创建一个带头指针的链表。
代码:

class Solution {
public:
    ListNode* reverseBetween(ListNode* head, int left, int right) {
        if(left >= right) return head;
        ListNode *dummyNode = new ListNode(-1);
        dummyNode->next = head;
        ListNode*p,*q,*curr;
        p = dummyNode;
        for(int i = 0; i < left-1; i++){
            p = p->next;
        }
        curr = p->next;
        for(int i = 0; i < right - left; i++){
            q = curr->next;
            curr->next = q->next;
            q->next = p->next;
            p->next = q;
        }
        return dummyNode->next;
    }
};

41. 缺失的第一个正数

链接: 缺失的正数
难度: 困难
题目:
题目描述

运行示例:

运行示例

思路:
对于一个长度为 N 的数组,其中没有出现的最小正整数只能在 [1,N+1] 中.我用的是哈希表的思路,但是空间复杂度不符合题意。我看了题解,他们用的是置换和搞一个标记。置换是指将出现过的的整数置换到数组的对应位置,大于n+1的直接舍弃。搞一个标记即对出现过的整数在数组对应位置上加一个负号,然后遍历第一个是正数的位置即为结果。

代码:
置换:

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        int n = nums.size();
        for(int i = 0; i < n; i++){
            while(nums[i] > 0 && nums[i] <= n && nums[nums[i] -1 ] != nums[i]){
                swap(nums[nums[i] - 1], nums[i]);
            } 
        }
        for(int i = 0; i < n; i++){
            if(nums[i] != i+1){
                return i + 1;
            }
        }
        return n + 1;
    }
};

标记

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        int n = nums.size();
        for(int i = 0; i < n; i++){
            if(nums[i] <= 0){
                nums[i] = n + 1;
            }
        }
        for(int i = 0; i < n; i++){
            int num = abs(nums[i]);
            if(num <= n){
                nums[num - 1] = -abs(nums[num - 1]);
            }
        }
        for(int i = 0; i < n; i++){
            if(nums[i] > 0 ){
                return i + 1;
            }
        }
        return n + 1;
    }
};
  • 19
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值