• 1.Two Sum


    Description

       Given an array of integers, return indices of the two numbers such that they add up to a specific target.

    You may assume that each input would have exactly one solution, and you may not use the same element twice.

    Example:

    Given nums = [2, 7, 11, 15], target = 9,
    Because nums[0] + nums[1] = 2 + 7 = 9,
    return [0, 1].
    题目传送门

    一.题目理解

       这是LeetCode的第一道题目,LeetCode和之前刷的OJ有些不同,不用完全提交程序(包含main函数),是侧重算法的,我们只需要完成算法就好。
       下面说题目:这道题很好理解,给定一个数组,里面有很多整数,然后给定一个目标值,题目假设数组中刚好有两个数字之和等于目标值,我们需要找到这两个数字,并返回其下标。

    二.题目解答

    1.暴力求解

    1.1 思路和代码

    首先能想到的就是暴力求解,这种方法很简单,但是效率不高。

    //Brute Force
    class Solution {
    public:
        vector<int> twoSum(vector<int>& nums, int target) {
         
            vector<int> ret;
            
            for(int i = 0;i < nums.size();i++){
                
                for(int j = i + 1;j < nums.size();j++){
                    if(nums[i] + nums[j] == target){
                        ret.push_back(i);
                        ret.push_back(j);
                        break;
                    }                            
                }                        
            }  
            
            return ret;
        }
    };

       

    1.2 复杂度分析

    • 时间复杂度:O(n2) .对每一个元素,我们都要搜索剩余元素中有无匹配元素(两者之和为目标值),每一个元素花费的时间为O(n),总的时间为 O(n2).
    • 空间复杂度:O(1).

    1.3 效果

    image

    2.优化

        这里的优化主要是根据Solution的指导而来,有两种优化Two-pass Hash Table, One-pass Hash Table。

    2.1 Two-pass Hash Table

    2.1.1 思路和代码

        为了降低时间复杂度,我们应该采用一个更合理的方式去进行匹配元素的搜索,由题目我们可以知道匹配元素一定存在且唯一,同时要求返回匹配元素的下标;考虑到匹配元素和其下标的匹配,自然联想到Hash表。
        通过哈希表我们可以把搜索一个元素的匹配元素的花费由O(n)降为O(1),不过代价是增加了空间开销,我们需要存储哈希表。尽管哈希表在有碰撞的情况下搜索花费能达到O(n),但是本题目刚好是有唯一解,这也就表示碰撞不会发生,因而我们可以大胆采用哈希表。
        由于匹配元素是唯一的,所以我们可以考虑无序表unorderded_map,使用元素的具体值作为键值,其下标作为映射值。
    //Two-pass Hash Table
    class Solution {
    public:
        vector<int> twoSum(vector<int>& nums, int target) {
    
            unordered_map<int,int> m;
            vector<int> ret;
    
            for(int i = 0; i < nums.size(); i++)
                m[nums[i]] = i;
    
            for(int i = 0; i < nums.size(); i++) {
                int complement = target - nums[i];
    
                if(m.count(complement) && m[complement] != i) {
                    ret.push_back(i);
                    ret.push_back(m[complement]);
                    break;
                }
            }
            return ret;
        }
    };

    2.1.2 复杂度分析

    • 时间复杂度:O(n)
    • 空间复杂度:O(n)

    2.1.3 效果

    image

    2.2 One-pass Hash Table

    2.2.1 思路和代码

       上述的结果证明我们的思路是正确的,其实我们还可以继续优化,可以在生成哈希表的过程进行搜索,从而进一步提高速度,降低时间复杂度。

    //One-pass Hash Table
    class Solution {
    public:
        vector<int> twoSum(vector<int>& nums, int target) {
    
            unordered_map<int,int> m;
            vector<int> ret;
    
            for(int i = 0;i < nums.size();i++){
    
                if(m.count(target - nums[i])){
                    ret.push_back(i);
                    ret.push_back(m[target-nums[i]]);
                    return ret;
                }
                m[nums[i]] = i;
    
            }
            
        }
    };

    2.2.2 复杂度分析

    • 时间复杂度: O(n)
    • 空间复杂度: O(n)

    2.2.3 效果

    image
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
  • 相关阅读:
    在搜索引擎中输入汉字就可以解析到对应的域名,请问如何用LoadRunner进行测试。
    面向对象
    三种循环结构语句
    JAVA复习题(一)基础知识
    JVM快速入门(上)
    count(*) 优化
    .jquery中$.get()提交和$.post()提交有区别吗?
    window.onload()函数和jQuery中的document.ready()有什么区别?
    假设有一个文本框要求输入10个字符的邮政编码,对于该文本框应该怎样划分等价类?
    软件测试项目从什么时候开始,?为什么?
  • 原文地址:https://www.cnblogs.com/ovs98/p/9830579.html
Copyright © 2020-2023  润新知