[leetcode每日一题2021/2/1]888. 公平的糖果棒交换

题目来源于leetcode,解法和思路仅代表个人观点。传送门
难度:简单(也不见得简单啊)
时间:20min

题目

爱丽丝和鲍勃有不同大小的糖果棒:A[i] 是爱丽丝拥有的第 i 根糖果棒的大小,B[j] 是鲍勃拥有的第 j 根糖果棒的大小。

因为他们是朋友,所以他们想交换一根糖果棒,这样交换后,他们都有相同的糖果总量。(一个人拥有的糖果总量是他们拥有的糖果棒大小的总和。)

返回一个整数数组 ans,其中 ans[0] 是爱丽丝必须交换的糖果棒的大小,ans[1] 是 Bob 必须交换的糖果棒的大小。

如果有多个答案,你可以返回其中任何一个。保证答案存在。

示例 1:

输入:A = [1,1], B = [2,2]
输出:[1,2]

示例 2:

输入:A = [1,2], B = [2,3]
输出:[1,2]

示例 3:

输入:A = [2], B = [1,3]
输出:[2,3]

示例 4:

输入:A = [1,2,5], B = [2,4]
输出:[5,4]

提示:

1 <= A.length <= 10000
1 <= B.length <= 10000
1 <= A[i] <= 100000
1 <= B[i] <= 100000
保证爱丽丝与鲍勃的糖果总量不同。
答案肯定存在。

思路

交换之后,总量相等,就有公式:
a = s u m a l i c e + s u m b o b 2 + b a = {sum_{alice}+sum_{bob} \over 2} + b a=2sumalice+sumbob+b
其中, a ∈ a l i c e a \isin alice aalice b ∈ b o b b \isin bob bbob

O(n²)

依次枚举,遍历完n²,超时

O(nlogm)

这里可以比较alice和bob数组的大小,使用较大的一遍二分查找,快一点。
枚举一边,二分查找另一边,超时

看了一下评论区,如果两边都使用二分查找的话,好像能过。

O(max(n,m))

枚举一边,另一边用哈希set查找,通过

如果使用alice与bob较大的一方做hashset的话,时间复杂度可以达到O(min(n,m))。


所以,分析算法时间复杂度,可以让思维能有一个递进的过程。

代码

class Solution {
public:
    //二分查找,保证arr有序
    // bool find(vector<int> arr,int target,int l,int r){
    //     if(l>r){
    //         return false;
    //     }
    //     int mid = (l + r)/2;
    //     if(arr[mid] == target){
    //         return true;
    //     }
    //     return find(arr,target,l,mid-1) || find(arr,target,mid+1,r);
    // }
    vector<int> fairCandySwap(vector<int>& A, vector<int>& B) {
        int alice = 0;
        int bob = 0;
        vector<int> ans;
        for(auto a:A){
            alice += a;
        }
        for(auto b:B){
            bob += b;
        }
        //n²过不了
        // for(int i=0;i<A.size();i++){
        //     for(int j=0;j<B.size();j++){
        //         if(alice-A[i]+B[j] == bob-B[j]+A[i]){
        //             return vector<int>{A[i],B[j]};
        //         }
        //     }
        // }

        // nlog(m)过不了
        // sort(B.begin(),B.end());
        // //知道:a = (alice-bob)/2 + b
        // for(int i=0;i<A.size();i++){
        //     int a = A[i];
        //     int b = a - (alice-bob)/2;
        //     if(find(B,b,0,B.size()-1)){
        //         return vector<int>{a,b};
        //     }
        // }

        unordered_set<int> set;
        // 时间:max(n,m)
        // 空间:max(n,m)
        // 哈希映射
        for(int j=0;j<B.size();j++){
            set.insert(B[j]);
        }
        for(int i=0;i<A.size();i++){
            int a = A[i];
            int b = a - (alice-bob)/2;
            if(set.count(b)){
                return vector<int>{a,b};
            }
        }
        return ans;
    }
};

算法复杂度

时间复杂度: 使用hashset的话,可以达到O(max(m,n))。n,m分别为两个数组的长度。

空间复杂度: O(max(n,m))。n,m分别为两个数组的长度。

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值