题解 | #和为S的两个数字#

和为S的两个数字

https://www.nowcoder.com/practice/390da4f7a00f44bea7c2f3d19491311b?tpId=13&&tqId=11195&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

题解一: 暴力
解题思路: 双层循环,在确定第一个值array[i]的情况下,遍历其余所有值,找到相匹配的array[j],找到即可结束循环
复杂度分析:
时间复杂度: O(n^2)
空间复杂度: O(1)

class Solution {
public:
    vector<int> FindNumbersWithSum(vector<int> array,int sum){
        for(int i = 0;i<array.size();i++){//确定第一个数
            for(int j = i+1;j<array.size();j++){
                if(array[i] + array[j] == sum)//判断两数之和是否为S
                {
                    return {array[i],array[j]};//C++11语法,返回结果
                }
            }
        }
        return {};//没有找到,返回空数组
    }
};

题解二:二分查找
解题思路: 利用数组递增排序的特性,满足二分查找条件。
主要思路:

  1. 假设当前值为arr[i], 那么第二个数为sum-arr[i]。
  2. sum-arr[i] 与 arr[i]的大小分为三种情况:
    a. 如果sum-arr[i] arr[i]相等,那么只需要查找i两侧的值;
    b. 如果sum-arr[i]小于arr[i],那么在i 的左侧查找sum-arr[i];
    c. 如果sum-arr[i]大于arr[i], 那么在i 的右测查找sum-arr[i];
    示例:
    图片说明

复杂度分析:
时间复杂度: O(nlog n )
空间复杂度: O(1)

class Solution {
public:
bool binary_search(const vector<int> &v,int l,int r,int target){
 bool ret = false;
 if(l<0 || l>=v.size() || r<0 || r>=v.size()) return ret;
 while(l<r){
     int mid = (l+r)/2;
     if(v[mid] >= target) r = mid;
     else l = mid+1;
 }
 return v[l] == target;
}
vector<int> construct_ans(int a,int b){
     vector<int> ans = vector<int>{a,b};
     sort(ans.begin(),ans.end());
     return ans;
}
vector<int> FindNumbersWithSum(vector<int> array,int sum){
 for(int i = 0;i<array.size();i++){
     int target = sum - array[i];
     bool ret = false;
     //情况三
     if(target>array[i])
     {
         ret = binary_search(array,i+1,array.size()-1,target);
         if(ret) return construct_ans(array[i], target);
     }
     //情况二
     else if ( target < array[i] )
     {
         ret = binary_search(array,0,i-1,target);
         if(ret) return construct_ans(array[i],target);
     }
     //情况一
     else
     {
         if(i-1>=0 &&  array[i-1] == array[i] || i+1<array.size() && array[i+1] == array[i]) return construct_ans(target,target);
     }
 }
 return {};
}
};

题解三:双指针
解题思路: 利用数组递增排序的特性。
主要思路:

  1. 使用left 表示左边指向的值,使用right 表示右边指向的值。
  2. (left + right) 与 sum 大小情况 a. (left right)> sum, 则r--, 降低两数之和;
    b. (left + right) < sum, 则l ++,增大两数之和;
    c. (left + right) == sum ,则返回;
    示例:
    图片说明
    复杂度分析:
    时间复杂度: O(n)
    空间复杂度: O(1)
    class Solution {
    public:
     vector<int> FindNumbersWithSum(vector<int> array,int sum){
         int left = 0, right = array.size()-1;
         while(left<right)
         {
             if(sum == array[left] + array[right] )//(left + right) == sum ,则返回;
             {
                 return vector<int>{array[left],array[right]};
             }
             else if ( sum > array[left] + array[right] )//(left + right) < sum, 则l ++,增大两数之和;
             {
                 left++;
             }
             else right--;//(left + right) > sum, 则r--, 降低两数之和;
         }
         return {};
     }
    };
    相关题集:
    反转字符串
    滑动窗口的最大值
牛客网编程题题解 文章被收录于专栏

本专栏记录在牛客网上AC的每一题,写下题解。 未来2年完成2000编程题的题解。 2021.12.29更新,最进准备毕设,断更了,会尽快做完毕设,继续做这一件事情

全部评论

相关推荐

不愿透露姓名的神秘牛友
10-12 10:48
已编辑
秋招之苟:邻居家老哥19届双2硕大厂开发offer拿遍了,前几天向他请教秋招,他给我看他当年的简历,0实习实验室项目技术栈跟开发基本不沾边😂,我跟他说这个放在现在中厂简历都过不了
点赞 评论 收藏
分享
11-01 08:48
门头沟学院 C++
伤心的候选人在吵架:佬你不要的,能不能拿户口本证明过户给我。。球球了
点赞 评论 收藏
分享
服从性笔试吗,发这么多笔,现在还在发。
蟑螂恶霸zZ:傻 x 公司,发两次笔试,两次部门匹配挂,
投递金山WPS等公司10个岗位 >
点赞 评论 收藏
分享
4 1 评论
分享
牛客网
牛客企业服务