查找两个相关索引,其中两个元素的总和等于目标值

时间:2017-12-04 20:23:28

标签: c++ algorithm

背景

给定一个整数数组,返回两个数字的索引,使它们相加到特定目标。

您可以假设每个输入只有一个解决方案,并且您可能不会两次使用相同的元素。

示例:

给定nums = [2,7,11,15],target = 9,

因为nums [0] + nums [1] = 2 + 7 = 9,

返回[0,1]。

问题:

我有一个数字1,2,3,4,5的列表。我的目标值是8,所以我应该返回索引2和4.我的第一个想法是编写一个double for循环,检查是否从列表中添加两个元素将获得我的目标值。虽然,在检查是否有这样的解决方案时,我的代码返回没有。

这是我的代码:

#include <iostream>
#include <vector>
using namespace std;


int main() {

    vector<int> list;
    list.push_back(1);
    list.push_back(2);
    list.push_back(3);
    list.push_back(4);
    list.push_back(5);

    int target = 8;


    string result;
    for(int i = 0; i < list.size(); i++) {
        for(int j = i+1; j < list.size(); j++) {
            if(list[i] + list[j] == target) {
                result = "There is a solution";
            }
            else {
                result = "There is no solution";
            }
        }

    }

    cout << result << endl;


    return 0;
}

也许我的方法/想法是完全错误的。任何人都可以提供解决这个问题的任何提示或建议吗?

3 个答案:

答案 0 :(得分:2)

您的方法是正确的,但是您忘记了在找到解决方案后仍处于循环中。

这会让你半途而废。我建议将两个循环放在一个函数中,并在找到匹配后返回。你可以做的一件事是从该函数返回pair<int,int>,或者你可以简单地从循环中的那一点输出结果。

bool solutionFound = false;
int i,j;

for(i = 0; i < list.size(); i++) 
{
    for(j = i+1; j < list.size(); j++) 
    {
        if(list[i] + list[j] == target) 
        {
            solutionFound = true;
        }
    }
}

这是函数方法的样子:

pair<int, int> findSolution(vector<int> list, int target)
{
  for (int i = 0; i < list.size(); i++)
  {
    for (int j = i + 1; j < list.size(); j++)
    {
      if (list[i] + list[j] == target)
      {
        return pair<int, int>(i, j);
      }
    }
  }
  return pair<int, int>(-1, -1);
}

int main() {

  vector<int> list;
  list.push_back(1);
  list.push_back(2);
  list.push_back(3);
  list.push_back(4);
  list.push_back(5);

  int target = 8;
  pair<int, int> results = findSolution(list, target);
  cout << results.first << " " << results.second << "\n";

  return 0;
}

这是C ++结合Dave的线性执行时间答案和一些有用的评论:

pair<int, int> findSolution(vector<int> list, int target)
{
  unordered_map<int, int> valueToIndex;
  for (int i = 0; i < list.size(); i++)
  {
    int needed = target - list[i];
    auto it = valueToIndex.find(needed);
    if (it != valueToIndex.end())
    {
      return pair<int, int>(it->second, i);
    }
    valueToIndex.emplace(list[i], i);
  }
  return pair<int, int>(-1, -1);
}

int main() 
{
  vector<int> list = { 1,2,3,4,5 };
  int target = 10;
  pair<int, int> results = findSolution(list, target);
  cout << results.first << " " << results.second << "\n";
}

答案 1 :(得分:2)

你在n ^ 2时间做这件事。通过对每个元素进行散列,并检查每个元素以查看它是否补充wrt,在线性时间内解决它。你试图实现的总数是哈希值。

,例如1,2,3,4,5,目标为8

indx 0, val 1: 7 isn't in the map; H[1] = 0
indx 1, val 2: 6 isn't in the map, H[2] = 1
indx 2, val 3: 5 isn't in the map, H[3] = 2
indx 3, val 4: 4 isn't in the map, H[4] = 3
indx 4, val 5: 3 is in the map. H[3] = 2. Return 2,4

代码,按要求(Ruby)

def get_indices(arr, target)
    value_to_index = {}
    arr.each_with_index do |val, index|
        if value_to_index.has_key?(target - val)
            return [value_to_index[target - val], index] 
        end
        value_to_index[val] = index
    end
end

get_indices([1,2,3,4,5], 8)

答案 2 :(得分:1)

基本上与zzxyz的最新编辑相同,但速度更快,更脏。

#include <iostream>
#include <vector>

bool FindSolution(const std::vector<int> &list, // const reference. Less copying
                  int target)
{
    for (int i: list) // Range-based for (added in C++11)
    {
        for (int j: list)
        {
            if (i + j == target) // i and j are the numbers from the vector. 
                                 // no need for indexing
            {
                return true;
            }
        }
    }
    return false;
}

int main()
{
    std::vector<int> list{1,2,3,4,5}; // Uniform initialization Added in C++11. 
                                      // No need for push-backs of fixed data

    if (FindSolution(list, 8))
    {
        std::cout << "There is a solution\n";
    }
    else
    {
        std::cout << "There is no solution\n";
    }

    return 0;
}