LeetCode 热题 C++ 416. 分割等和子集 437. 路径总和 III 438. 找到字符串中所有字母异位词 448. 找到所有数组中消失的数字 461. 汉明距离 494. 目标和

39 篇文章 0 订阅
19 篇文章 0 订阅

LeetCode 416. 分割等和子集

给你一个 只包含正整数 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。

示例 1:

输入:nums = [1,5,11,5]
输出:true
解释:数组可以分割成 [1, 5, 5] 和 [11] 。

示例 2:

输入:nums = [1,2,3,5]
输出:false
解释:数组不能分割成两个元素和相等的子集。

提示:

  • 1 <= nums.length <= 200
  • 1 <= nums[i] <= 100

思路:

第一遍想简单了,于是遇到了1 1 2 2就WA了。

看了讨论区说是01背包,所以换动规来做。

先确认背包的总和,假如总和是奇数的话可以直接确定返回值是false。如果是偶数,那我们的背包问题就变成了背包能否取到价值为总数一半的背包。

(悄悄说一句,auto大法好)

代码:

class Solution {
public:
    bool dp[100005];
    bool canPartition(vector<int>& nums) {
        int n=nums.size();
        int sum =0;
        for(auto i:nums)sum+=i;
        if(sum%2==1)return 0;
        sum=sum/2;
        dp[0]=true;
        for(int i=0;i<n;i++)
        {
            for(int j=sum;j>=nums[i];j--)
            {
                dp[j]=dp[j]||dp[j-nums[i]];
            }
        }
        return dp[sum];
    }
};

LeetCode 437

给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum路径 的数目。

路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。

示例 1:

输入:root = [10,5,-3,3,2,null,11,3,-2,null,1], targetSum = 8
输出:3
解释:和等于 8 的路径有 3 条,如图所示。

示例 2:

输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:3

提示:

  • 二叉树的节点个数的范围是 [0,1000]
  • -109 <= Node.val <= 109 
  • -1000 <= targetSum <= 1000 

思路:

用curr存入每个结点的前缀和(不包括该结点),如果curr-targerSum出现过,那就+1.

代码:

/**
 * 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:
    unordered_map<long long, int> m;
    int dfs(TreeNode* root, int targetSum,long long curr)
    {
        if(!root)return 0;
        int ret=0;
        curr+=root->val;
        if(m.count(curr-targetSum))
        {
            ret=m[curr-targetSum];
        }
        m[curr]++;
        ret += dfs(root->left, targetSum,curr);
        ret += dfs(root->right, targetSum,curr);
        m[curr]--;

        return ret;
    }
    int pathSum(TreeNode* root, int targetSum) {
        m[0]=1;
        return dfs(root,targetSum,0);
    }
};

LeetCode438

给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。

异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。

示例 1:

输入: s = "cbaebabacd", p = "abc"
输出: [0,6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。

 示例 2:

输入: s = "abab", p = "ab"
输出: [0,1,2]
解释:
起始索引等于 0 的子串是 "ab", 它是 "ab" 的异位词。
起始索引等于 1 的子串是 "ba", 它是 "ab" 的异位词。
起始索引等于 2 的子串是 "ab", 它是 "ab" 的异位词。

提示:

  • 1 <= s.length, p.length <= 3 * 104
  • s 和 p 仅包含小写字母

思路:

滑动窗口

代码:

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        int n=s.length();
        int m=p.length();
        vector<int> v;
        if(n<m)return v;
        vector<int> sCount(26);
        vector<int> pCount(26);
        for(int i=0;i<m;i++)
        {
            sCount[s[i]-'a']++;
            pCount[p[i]-'a']++;
        }
        if(sCount==pCount)v.push_back(0);
        for(int i=0;i<n-m;i++)
        {
            sCount[s[i]-'a']--;
            sCount[s[i+m]-'a']++;
            if(sCount==pCount)v.push_back(i+1);
        }
        return v;
    }
};

LeetCode448

给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间 [1, n] 内。请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数字,并以数组的形式返回结果。

示例 1:

输入:nums = [4,3,2,7,8,2,3,1]
输出:[5,6]

示例 2:

输入:nums = [1,1]
输出:[2]

提示:

  • n == nums.length
  • 1 <= n <= 105
  • 1 <= nums[i] <= n

进阶:你能在不使用额外空间且时间复杂度为 O(n) 的情况下解决这个问题吗? 你可以假定返回的数组不算在额外空间内。

思路:

把每个值放在它应该有的位置上,那么最后遍历值不配位的位置就是缺少的位置。

代码:

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

LeetCode 461

两个整数之间的 汉明距离 指的是这两个数字对应二进制位不同的位置的数目。

给你两个整数 xy,计算并返回它们之间的汉明距离。

示例 1:

输入:x = 1, y = 4
输出:2
解释:
1   (0 0 0 1)
4   (0 1 0 0)
       ↑   ↑
上面的箭头指出了对应二进制位不同的位置。

示例 2:

输入:x = 3, y = 1
输出:1

提示:

  • 0 <= x, y <= 231 - 1

思路:

暴力。

代码:

class Solution {
public:
    int hammingDistance(int x, int y) {
        int s=max(x,y);
        int sum=0;
        while(s)
        {
            if(x%2!=y%2)sum++;
            x=x/2;
            y=y/2;
            s=s/2;
        }
        return sum;
    }
};

LeetCode494

给你一个整数数组 nums 和一个整数 target

向数组中的每个整数前添加 '+''-' ,然后串联起所有整数,可以构造一个 表达式

  • 例如,nums = [2, 1] ,可以在 2 之前添加 '+' ,在 1 之前添加 '-' ,然后串联起来得到表达式 "+2-1"

返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目。

示例 1:

输入:nums = [1,1,1,1,1], target = 3
输出:5
解释:一共有 5 种方法让最终目标和为 3 。
-1 + 1 + 1 + 1 + 1 = 3
+1 - 1 + 1 + 1 + 1 = 3
+1 + 1 - 1 + 1 + 1 = 3
+1 + 1 + 1 - 1 + 1 = 3
+1 + 1 + 1 + 1 - 1 = 3

示例 2:

输入:nums = [1], target = 1
输出:1

提示:

  • 1 <= nums.length <= 20
  • 0 <= nums[i] <= 1000
  • 0 <= sum(nums[i]) <= 1000
  • -1000 <= target <= 1000

 

 思路:

不想思考了,直接dfs吧)

代码:

class Solution {
public:
    int ans=0;
    void dfs(vector<int>& nums, int target,int i,int sum)
    {
        if(i==nums.size()){
            if(sum==target)ans++;
        }
        else{
            dfs(nums,target,i+1,sum+nums[i]);
            dfs(nums,target,i+1,sum-nums[i]);
        }
        
    }
    int findTargetSumWays(vector<int>& nums, int target) {
        dfs(nums,target,0,0);
        return ans;
    }
};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值