Algorithm that finds two numbers that sum to a target

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
1
down vote

favorite












Is this the optimal algorithm to satisfy this problem?



It does work. I get the: 1 and 5 (or 5 and 1) as 1 + 9 = 10.




Here's a function that, when passed a list and a target sum, returns two distinct zero-based indices of any two of the numbers, whose sum is equal to the target sum. If there are no two numbers, the function should return null.



For example, FindTwoSum(new List() 3, 1, 5, 7, 5, 9 , 10) should return a Tuple containing any of the following pairs of indices:



  • 0 and 3 (or 3 and 0) as 3 + 7 = 10

  • 1 and 5 (or 5 and 1) as 1 + 9 = 10

  • 2 and 4 (or 4 and 2) as 5 + 5 = 10


Someone had suggested the following, but I was not sure how to code it.



Order the data. Start at the left and the right at the same time. Add the left most and the right most entries. If the total is too high, move from the right towards the center. If the total is too low, move from the left towards the center.



So I came up with the following. It has 3 loop constructs though.




namespace AlgorithmFind2Sum

class TwoSum

public static void Main(string args)

// This set of data will find a match that adds up to the sum.
Tuple<int, int> indices = FindTwoSum(new List<int>() 3, 1, 5, 7, 5, 9 , 10);

// This set of data will NOT find a match that adds up to the sum.
//Tuple<int, int> indices = FindTwoSum(new List<int>() 1, 2, 4, 5, 7, 7 , 10);

if (indices != null)

// Write.
Console.WriteLine("Entry that added up to the sum: " + indices.Item1 + " " + indices.Item2);

// Reads the next line.
Console.ReadLine();

else

// Write.
Console.WriteLine("None added up to the sum.");

// Reads the next line.
Console.ReadLine();



public static Tuple<int, int> FindTwoSum(IList<int> list, int sum)

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Order the data - sort it.
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

// Using LINQ OrderBy method (it will generate new List<int> with items sorted):
var orderedList = list.OrderBy(x => x).ToList();

string finished = "N";
string found = "N";
string firstOuterLoopEntry = "Y";
int outerLoopCount = 0;
int innerLoopCount = 0;
int loopUpperBound = list.Count - 1;
int SumOfTwo = 0;

// Loops as long as the condition is true.
while (finished == "N")

while (outerLoopCount < orderedList.Count)

innerLoopCount = 0;

while (innerLoopCount < loopUpperBound)

if (firstOuterLoopEntry == "Y")

SumOfTwo = orderedList[outerLoopCount] + orderedList[innerLoopCount + 1];

if (SumOfTwo == sum)

found = "Y";
break;


else

// Set the loop upper bound here again in that I have to make up for skipping the entry that is itself.
loopUpperBound = orderedList.Count;

// Do not process the entry that is itself.
if (innerLoopCount != outerLoopCount)

SumOfTwo = orderedList[outerLoopCount] + orderedList[innerLoopCount];

if (SumOfTwo == sum)

found = "Y";
break;




innerLoopCount = innerLoopCount + 1;


if (found == "Y")

finished = "Y";
break;

else

firstOuterLoopEntry = "N";

outerLoopCount = outerLoopCount + 1;



finished = "Y";


// Return.
if (found == "Y")

return Tuple.Create(orderedList[outerLoopCount], orderedList[innerLoopCount + 1]);

else

return null;










share|improve this question

















  • 2




    This is very convoluted in my opinion.
    – paparazzo
    Jul 11 at 14:06










  • Please see What to do when someone answers. I have rolled back Rev 6 → 5.
    – 200_success
    Jul 11 at 17:27
















up vote
1
down vote

favorite












Is this the optimal algorithm to satisfy this problem?



It does work. I get the: 1 and 5 (or 5 and 1) as 1 + 9 = 10.




Here's a function that, when passed a list and a target sum, returns two distinct zero-based indices of any two of the numbers, whose sum is equal to the target sum. If there are no two numbers, the function should return null.



For example, FindTwoSum(new List() 3, 1, 5, 7, 5, 9 , 10) should return a Tuple containing any of the following pairs of indices:



  • 0 and 3 (or 3 and 0) as 3 + 7 = 10

  • 1 and 5 (or 5 and 1) as 1 + 9 = 10

  • 2 and 4 (or 4 and 2) as 5 + 5 = 10


Someone had suggested the following, but I was not sure how to code it.



Order the data. Start at the left and the right at the same time. Add the left most and the right most entries. If the total is too high, move from the right towards the center. If the total is too low, move from the left towards the center.



So I came up with the following. It has 3 loop constructs though.




namespace AlgorithmFind2Sum

class TwoSum

public static void Main(string args)

// This set of data will find a match that adds up to the sum.
Tuple<int, int> indices = FindTwoSum(new List<int>() 3, 1, 5, 7, 5, 9 , 10);

// This set of data will NOT find a match that adds up to the sum.
//Tuple<int, int> indices = FindTwoSum(new List<int>() 1, 2, 4, 5, 7, 7 , 10);

if (indices != null)

// Write.
Console.WriteLine("Entry that added up to the sum: " + indices.Item1 + " " + indices.Item2);

// Reads the next line.
Console.ReadLine();

else

// Write.
Console.WriteLine("None added up to the sum.");

// Reads the next line.
Console.ReadLine();



public static Tuple<int, int> FindTwoSum(IList<int> list, int sum)

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Order the data - sort it.
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

// Using LINQ OrderBy method (it will generate new List<int> with items sorted):
var orderedList = list.OrderBy(x => x).ToList();

string finished = "N";
string found = "N";
string firstOuterLoopEntry = "Y";
int outerLoopCount = 0;
int innerLoopCount = 0;
int loopUpperBound = list.Count - 1;
int SumOfTwo = 0;

// Loops as long as the condition is true.
while (finished == "N")

while (outerLoopCount < orderedList.Count)

innerLoopCount = 0;

while (innerLoopCount < loopUpperBound)

if (firstOuterLoopEntry == "Y")

SumOfTwo = orderedList[outerLoopCount] + orderedList[innerLoopCount + 1];

if (SumOfTwo == sum)

found = "Y";
break;


else

// Set the loop upper bound here again in that I have to make up for skipping the entry that is itself.
loopUpperBound = orderedList.Count;

// Do not process the entry that is itself.
if (innerLoopCount != outerLoopCount)

SumOfTwo = orderedList[outerLoopCount] + orderedList[innerLoopCount];

if (SumOfTwo == sum)

found = "Y";
break;




innerLoopCount = innerLoopCount + 1;


if (found == "Y")

finished = "Y";
break;

else

firstOuterLoopEntry = "N";

outerLoopCount = outerLoopCount + 1;



finished = "Y";


// Return.
if (found == "Y")

return Tuple.Create(orderedList[outerLoopCount], orderedList[innerLoopCount + 1]);

else

return null;










share|improve this question

















  • 2




    This is very convoluted in my opinion.
    – paparazzo
    Jul 11 at 14:06










  • Please see What to do when someone answers. I have rolled back Rev 6 → 5.
    – 200_success
    Jul 11 at 17:27












up vote
1
down vote

favorite









up vote
1
down vote

favorite











Is this the optimal algorithm to satisfy this problem?



It does work. I get the: 1 and 5 (or 5 and 1) as 1 + 9 = 10.




Here's a function that, when passed a list and a target sum, returns two distinct zero-based indices of any two of the numbers, whose sum is equal to the target sum. If there are no two numbers, the function should return null.



For example, FindTwoSum(new List() 3, 1, 5, 7, 5, 9 , 10) should return a Tuple containing any of the following pairs of indices:



  • 0 and 3 (or 3 and 0) as 3 + 7 = 10

  • 1 and 5 (or 5 and 1) as 1 + 9 = 10

  • 2 and 4 (or 4 and 2) as 5 + 5 = 10


Someone had suggested the following, but I was not sure how to code it.



Order the data. Start at the left and the right at the same time. Add the left most and the right most entries. If the total is too high, move from the right towards the center. If the total is too low, move from the left towards the center.



So I came up with the following. It has 3 loop constructs though.




namespace AlgorithmFind2Sum

class TwoSum

public static void Main(string args)

// This set of data will find a match that adds up to the sum.
Tuple<int, int> indices = FindTwoSum(new List<int>() 3, 1, 5, 7, 5, 9 , 10);

// This set of data will NOT find a match that adds up to the sum.
//Tuple<int, int> indices = FindTwoSum(new List<int>() 1, 2, 4, 5, 7, 7 , 10);

if (indices != null)

// Write.
Console.WriteLine("Entry that added up to the sum: " + indices.Item1 + " " + indices.Item2);

// Reads the next line.
Console.ReadLine();

else

// Write.
Console.WriteLine("None added up to the sum.");

// Reads the next line.
Console.ReadLine();



public static Tuple<int, int> FindTwoSum(IList<int> list, int sum)

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Order the data - sort it.
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

// Using LINQ OrderBy method (it will generate new List<int> with items sorted):
var orderedList = list.OrderBy(x => x).ToList();

string finished = "N";
string found = "N";
string firstOuterLoopEntry = "Y";
int outerLoopCount = 0;
int innerLoopCount = 0;
int loopUpperBound = list.Count - 1;
int SumOfTwo = 0;

// Loops as long as the condition is true.
while (finished == "N")

while (outerLoopCount < orderedList.Count)

innerLoopCount = 0;

while (innerLoopCount < loopUpperBound)

if (firstOuterLoopEntry == "Y")

SumOfTwo = orderedList[outerLoopCount] + orderedList[innerLoopCount + 1];

if (SumOfTwo == sum)

found = "Y";
break;


else

// Set the loop upper bound here again in that I have to make up for skipping the entry that is itself.
loopUpperBound = orderedList.Count;

// Do not process the entry that is itself.
if (innerLoopCount != outerLoopCount)

SumOfTwo = orderedList[outerLoopCount] + orderedList[innerLoopCount];

if (SumOfTwo == sum)

found = "Y";
break;




innerLoopCount = innerLoopCount + 1;


if (found == "Y")

finished = "Y";
break;

else

firstOuterLoopEntry = "N";

outerLoopCount = outerLoopCount + 1;



finished = "Y";


// Return.
if (found == "Y")

return Tuple.Create(orderedList[outerLoopCount], orderedList[innerLoopCount + 1]);

else

return null;










share|improve this question













Is this the optimal algorithm to satisfy this problem?



It does work. I get the: 1 and 5 (or 5 and 1) as 1 + 9 = 10.




Here's a function that, when passed a list and a target sum, returns two distinct zero-based indices of any two of the numbers, whose sum is equal to the target sum. If there are no two numbers, the function should return null.



For example, FindTwoSum(new List() 3, 1, 5, 7, 5, 9 , 10) should return a Tuple containing any of the following pairs of indices:



  • 0 and 3 (or 3 and 0) as 3 + 7 = 10

  • 1 and 5 (or 5 and 1) as 1 + 9 = 10

  • 2 and 4 (or 4 and 2) as 5 + 5 = 10


Someone had suggested the following, but I was not sure how to code it.



Order the data. Start at the left and the right at the same time. Add the left most and the right most entries. If the total is too high, move from the right towards the center. If the total is too low, move from the left towards the center.



So I came up with the following. It has 3 loop constructs though.




namespace AlgorithmFind2Sum

class TwoSum

public static void Main(string args)

// This set of data will find a match that adds up to the sum.
Tuple<int, int> indices = FindTwoSum(new List<int>() 3, 1, 5, 7, 5, 9 , 10);

// This set of data will NOT find a match that adds up to the sum.
//Tuple<int, int> indices = FindTwoSum(new List<int>() 1, 2, 4, 5, 7, 7 , 10);

if (indices != null)

// Write.
Console.WriteLine("Entry that added up to the sum: " + indices.Item1 + " " + indices.Item2);

// Reads the next line.
Console.ReadLine();

else

// Write.
Console.WriteLine("None added up to the sum.");

// Reads the next line.
Console.ReadLine();



public static Tuple<int, int> FindTwoSum(IList<int> list, int sum)

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Order the data - sort it.
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

// Using LINQ OrderBy method (it will generate new List<int> with items sorted):
var orderedList = list.OrderBy(x => x).ToList();

string finished = "N";
string found = "N";
string firstOuterLoopEntry = "Y";
int outerLoopCount = 0;
int innerLoopCount = 0;
int loopUpperBound = list.Count - 1;
int SumOfTwo = 0;

// Loops as long as the condition is true.
while (finished == "N")

while (outerLoopCount < orderedList.Count)

innerLoopCount = 0;

while (innerLoopCount < loopUpperBound)

if (firstOuterLoopEntry == "Y")

SumOfTwo = orderedList[outerLoopCount] + orderedList[innerLoopCount + 1];

if (SumOfTwo == sum)

found = "Y";
break;


else

// Set the loop upper bound here again in that I have to make up for skipping the entry that is itself.
loopUpperBound = orderedList.Count;

// Do not process the entry that is itself.
if (innerLoopCount != outerLoopCount)

SumOfTwo = orderedList[outerLoopCount] + orderedList[innerLoopCount];

if (SumOfTwo == sum)

found = "Y";
break;




innerLoopCount = innerLoopCount + 1;


if (found == "Y")

finished = "Y";
break;

else

firstOuterLoopEntry = "N";

outerLoopCount = outerLoopCount + 1;



finished = "Y";


// Return.
if (found == "Y")

return Tuple.Create(orderedList[outerLoopCount], orderedList[innerLoopCount + 1]);

else

return null;












share|improve this question












share|improve this question




share|improve this question








edited Jul 11 at 17:36









200_success

123k14143399




123k14143399









asked Jul 11 at 13:34









user3020047

1093




1093







  • 2




    This is very convoluted in my opinion.
    – paparazzo
    Jul 11 at 14:06










  • Please see What to do when someone answers. I have rolled back Rev 6 → 5.
    – 200_success
    Jul 11 at 17:27












  • 2




    This is very convoluted in my opinion.
    – paparazzo
    Jul 11 at 14:06










  • Please see What to do when someone answers. I have rolled back Rev 6 → 5.
    – 200_success
    Jul 11 at 17:27







2




2




This is very convoluted in my opinion.
– paparazzo
Jul 11 at 14:06




This is very convoluted in my opinion.
– paparazzo
Jul 11 at 14:06












Please see What to do when someone answers. I have rolled back Rev 6 → 5.
– 200_success
Jul 11 at 17:27




Please see What to do when someone answers. I have rolled back Rev 6 → 5.
– 200_success
Jul 11 at 17:27










1 Answer
1






active

oldest

votes

















up vote
2
down vote













You sort but don't use the sort. Not getting why you need to reset loopUpperBound = orderedList.Count; Just start with that. Don't use Y N - use a Boolean. You are potentially evaluating each pair twice.



It is pretty simple:



public static Tuple<int, int> GetPair(List<int> ints, int sum)

int upperIndex = ints.Count - 1;
int lowerIndex = 0;
ints.Sort();
while (lowerIndex < upperIndex)

int curSum = ints[lowerIndex] + ints[upperIndex];
if (curSum == sum)

return new Tuple<int, int>(ints[lowerIndex], ints[upperIndex]);

if (curSum < sum)

lowerIndex++;

else

upperIndex--;


return null;



If you want to brute force it:



public static Tuple<int, int> GetPairBrute(List<int> ints, int sum)

for (int i = 0; i < ints.Count - 1; i++)

for (int j = i + 1; j < ints.Count; j++)

if (ints[i] + ints[j] == sum)

return new Tuple<int, int>(ints[i], ints[j]);



return null;






share|improve this answer



















  • 1




    Actually I do use the sorted list. Which becomes: 1,3,5,5,7,9 for the "find a match" test case and 1,2,4,5,7,7 for the "NOT find a match" test case.
    – user3020047
    Jul 11 at 17:11










  • However, I really do not need to sort the list after all.
    – user3020047
    Jul 11 at 17:45










  • Your brute force approach, for the "NOT find a match" test case, reduces down the number of entries processed in the 2nd pass and beyond. It's goes 5, then 4, then 3, then 2, then 1. My approach, for the "NOT find a match" test case, does not reduce down the number of entries processed. It's 5 processed each pass. For the "find a match" test case, we both are the same with regard to processing - 1 pass. So your solution is more efficient for sure.
    – user3020047
    Jul 11 at 17:53










  • The pretty simple approach seems to be the best and efficient. Starting at the left and the right at the same time. Add the left most and the right most entries. If the total is too high, move from the right towards the center. If the total is too low, move from the left towards the center.
    – user3020047
    Jul 11 at 18:40










  • Lastly, the line int loopUpperBound = List.Count - 1; should have been int loopUpperBound = orderedList.Count - 1; My mistake.
    – user3020047
    Jul 11 at 19:05










Your Answer




StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
);
);
, "mathjax-editing");

StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f198285%2falgorithm-that-finds-two-numbers-that-sum-to-a-target%23new-answer', 'question_page');

);

Post as a guest






























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
2
down vote













You sort but don't use the sort. Not getting why you need to reset loopUpperBound = orderedList.Count; Just start with that. Don't use Y N - use a Boolean. You are potentially evaluating each pair twice.



It is pretty simple:



public static Tuple<int, int> GetPair(List<int> ints, int sum)

int upperIndex = ints.Count - 1;
int lowerIndex = 0;
ints.Sort();
while (lowerIndex < upperIndex)

int curSum = ints[lowerIndex] + ints[upperIndex];
if (curSum == sum)

return new Tuple<int, int>(ints[lowerIndex], ints[upperIndex]);

if (curSum < sum)

lowerIndex++;

else

upperIndex--;


return null;



If you want to brute force it:



public static Tuple<int, int> GetPairBrute(List<int> ints, int sum)

for (int i = 0; i < ints.Count - 1; i++)

for (int j = i + 1; j < ints.Count; j++)

if (ints[i] + ints[j] == sum)

return new Tuple<int, int>(ints[i], ints[j]);



return null;






share|improve this answer



















  • 1




    Actually I do use the sorted list. Which becomes: 1,3,5,5,7,9 for the "find a match" test case and 1,2,4,5,7,7 for the "NOT find a match" test case.
    – user3020047
    Jul 11 at 17:11










  • However, I really do not need to sort the list after all.
    – user3020047
    Jul 11 at 17:45










  • Your brute force approach, for the "NOT find a match" test case, reduces down the number of entries processed in the 2nd pass and beyond. It's goes 5, then 4, then 3, then 2, then 1. My approach, for the "NOT find a match" test case, does not reduce down the number of entries processed. It's 5 processed each pass. For the "find a match" test case, we both are the same with regard to processing - 1 pass. So your solution is more efficient for sure.
    – user3020047
    Jul 11 at 17:53










  • The pretty simple approach seems to be the best and efficient. Starting at the left and the right at the same time. Add the left most and the right most entries. If the total is too high, move from the right towards the center. If the total is too low, move from the left towards the center.
    – user3020047
    Jul 11 at 18:40










  • Lastly, the line int loopUpperBound = List.Count - 1; should have been int loopUpperBound = orderedList.Count - 1; My mistake.
    – user3020047
    Jul 11 at 19:05














up vote
2
down vote













You sort but don't use the sort. Not getting why you need to reset loopUpperBound = orderedList.Count; Just start with that. Don't use Y N - use a Boolean. You are potentially evaluating each pair twice.



It is pretty simple:



public static Tuple<int, int> GetPair(List<int> ints, int sum)

int upperIndex = ints.Count - 1;
int lowerIndex = 0;
ints.Sort();
while (lowerIndex < upperIndex)

int curSum = ints[lowerIndex] + ints[upperIndex];
if (curSum == sum)

return new Tuple<int, int>(ints[lowerIndex], ints[upperIndex]);

if (curSum < sum)

lowerIndex++;

else

upperIndex--;


return null;



If you want to brute force it:



public static Tuple<int, int> GetPairBrute(List<int> ints, int sum)

for (int i = 0; i < ints.Count - 1; i++)

for (int j = i + 1; j < ints.Count; j++)

if (ints[i] + ints[j] == sum)

return new Tuple<int, int>(ints[i], ints[j]);



return null;






share|improve this answer



















  • 1




    Actually I do use the sorted list. Which becomes: 1,3,5,5,7,9 for the "find a match" test case and 1,2,4,5,7,7 for the "NOT find a match" test case.
    – user3020047
    Jul 11 at 17:11










  • However, I really do not need to sort the list after all.
    – user3020047
    Jul 11 at 17:45










  • Your brute force approach, for the "NOT find a match" test case, reduces down the number of entries processed in the 2nd pass and beyond. It's goes 5, then 4, then 3, then 2, then 1. My approach, for the "NOT find a match" test case, does not reduce down the number of entries processed. It's 5 processed each pass. For the "find a match" test case, we both are the same with regard to processing - 1 pass. So your solution is more efficient for sure.
    – user3020047
    Jul 11 at 17:53










  • The pretty simple approach seems to be the best and efficient. Starting at the left and the right at the same time. Add the left most and the right most entries. If the total is too high, move from the right towards the center. If the total is too low, move from the left towards the center.
    – user3020047
    Jul 11 at 18:40










  • Lastly, the line int loopUpperBound = List.Count - 1; should have been int loopUpperBound = orderedList.Count - 1; My mistake.
    – user3020047
    Jul 11 at 19:05












up vote
2
down vote










up vote
2
down vote









You sort but don't use the sort. Not getting why you need to reset loopUpperBound = orderedList.Count; Just start with that. Don't use Y N - use a Boolean. You are potentially evaluating each pair twice.



It is pretty simple:



public static Tuple<int, int> GetPair(List<int> ints, int sum)

int upperIndex = ints.Count - 1;
int lowerIndex = 0;
ints.Sort();
while (lowerIndex < upperIndex)

int curSum = ints[lowerIndex] + ints[upperIndex];
if (curSum == sum)

return new Tuple<int, int>(ints[lowerIndex], ints[upperIndex]);

if (curSum < sum)

lowerIndex++;

else

upperIndex--;


return null;



If you want to brute force it:



public static Tuple<int, int> GetPairBrute(List<int> ints, int sum)

for (int i = 0; i < ints.Count - 1; i++)

for (int j = i + 1; j < ints.Count; j++)

if (ints[i] + ints[j] == sum)

return new Tuple<int, int>(ints[i], ints[j]);



return null;






share|improve this answer















You sort but don't use the sort. Not getting why you need to reset loopUpperBound = orderedList.Count; Just start with that. Don't use Y N - use a Boolean. You are potentially evaluating each pair twice.



It is pretty simple:



public static Tuple<int, int> GetPair(List<int> ints, int sum)

int upperIndex = ints.Count - 1;
int lowerIndex = 0;
ints.Sort();
while (lowerIndex < upperIndex)

int curSum = ints[lowerIndex] + ints[upperIndex];
if (curSum == sum)

return new Tuple<int, int>(ints[lowerIndex], ints[upperIndex]);

if (curSum < sum)

lowerIndex++;

else

upperIndex--;


return null;



If you want to brute force it:



public static Tuple<int, int> GetPairBrute(List<int> ints, int sum)

for (int i = 0; i < ints.Count - 1; i++)

for (int j = i + 1; j < ints.Count; j++)

if (ints[i] + ints[j] == sum)

return new Tuple<int, int>(ints[i], ints[j]);



return null;







share|improve this answer















share|improve this answer



share|improve this answer








edited Jul 11 at 16:19


























answered Jul 11 at 15:05









paparazzo

4,8031730




4,8031730







  • 1




    Actually I do use the sorted list. Which becomes: 1,3,5,5,7,9 for the "find a match" test case and 1,2,4,5,7,7 for the "NOT find a match" test case.
    – user3020047
    Jul 11 at 17:11










  • However, I really do not need to sort the list after all.
    – user3020047
    Jul 11 at 17:45










  • Your brute force approach, for the "NOT find a match" test case, reduces down the number of entries processed in the 2nd pass and beyond. It's goes 5, then 4, then 3, then 2, then 1. My approach, for the "NOT find a match" test case, does not reduce down the number of entries processed. It's 5 processed each pass. For the "find a match" test case, we both are the same with regard to processing - 1 pass. So your solution is more efficient for sure.
    – user3020047
    Jul 11 at 17:53










  • The pretty simple approach seems to be the best and efficient. Starting at the left and the right at the same time. Add the left most and the right most entries. If the total is too high, move from the right towards the center. If the total is too low, move from the left towards the center.
    – user3020047
    Jul 11 at 18:40










  • Lastly, the line int loopUpperBound = List.Count - 1; should have been int loopUpperBound = orderedList.Count - 1; My mistake.
    – user3020047
    Jul 11 at 19:05












  • 1




    Actually I do use the sorted list. Which becomes: 1,3,5,5,7,9 for the "find a match" test case and 1,2,4,5,7,7 for the "NOT find a match" test case.
    – user3020047
    Jul 11 at 17:11










  • However, I really do not need to sort the list after all.
    – user3020047
    Jul 11 at 17:45










  • Your brute force approach, for the "NOT find a match" test case, reduces down the number of entries processed in the 2nd pass and beyond. It's goes 5, then 4, then 3, then 2, then 1. My approach, for the "NOT find a match" test case, does not reduce down the number of entries processed. It's 5 processed each pass. For the "find a match" test case, we both are the same with regard to processing - 1 pass. So your solution is more efficient for sure.
    – user3020047
    Jul 11 at 17:53










  • The pretty simple approach seems to be the best and efficient. Starting at the left and the right at the same time. Add the left most and the right most entries. If the total is too high, move from the right towards the center. If the total is too low, move from the left towards the center.
    – user3020047
    Jul 11 at 18:40










  • Lastly, the line int loopUpperBound = List.Count - 1; should have been int loopUpperBound = orderedList.Count - 1; My mistake.
    – user3020047
    Jul 11 at 19:05







1




1




Actually I do use the sorted list. Which becomes: 1,3,5,5,7,9 for the "find a match" test case and 1,2,4,5,7,7 for the "NOT find a match" test case.
– user3020047
Jul 11 at 17:11




Actually I do use the sorted list. Which becomes: 1,3,5,5,7,9 for the "find a match" test case and 1,2,4,5,7,7 for the "NOT find a match" test case.
– user3020047
Jul 11 at 17:11












However, I really do not need to sort the list after all.
– user3020047
Jul 11 at 17:45




However, I really do not need to sort the list after all.
– user3020047
Jul 11 at 17:45












Your brute force approach, for the "NOT find a match" test case, reduces down the number of entries processed in the 2nd pass and beyond. It's goes 5, then 4, then 3, then 2, then 1. My approach, for the "NOT find a match" test case, does not reduce down the number of entries processed. It's 5 processed each pass. For the "find a match" test case, we both are the same with regard to processing - 1 pass. So your solution is more efficient for sure.
– user3020047
Jul 11 at 17:53




Your brute force approach, for the "NOT find a match" test case, reduces down the number of entries processed in the 2nd pass and beyond. It's goes 5, then 4, then 3, then 2, then 1. My approach, for the "NOT find a match" test case, does not reduce down the number of entries processed. It's 5 processed each pass. For the "find a match" test case, we both are the same with regard to processing - 1 pass. So your solution is more efficient for sure.
– user3020047
Jul 11 at 17:53












The pretty simple approach seems to be the best and efficient. Starting at the left and the right at the same time. Add the left most and the right most entries. If the total is too high, move from the right towards the center. If the total is too low, move from the left towards the center.
– user3020047
Jul 11 at 18:40




The pretty simple approach seems to be the best and efficient. Starting at the left and the right at the same time. Add the left most and the right most entries. If the total is too high, move from the right towards the center. If the total is too low, move from the left towards the center.
– user3020047
Jul 11 at 18:40












Lastly, the line int loopUpperBound = List.Count - 1; should have been int loopUpperBound = orderedList.Count - 1; My mistake.
– user3020047
Jul 11 at 19:05




Lastly, the line int loopUpperBound = List.Count - 1; should have been int loopUpperBound = orderedList.Count - 1; My mistake.
– user3020047
Jul 11 at 19:05












 

draft saved


draft discarded


























 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f198285%2falgorithm-that-finds-two-numbers-that-sum-to-a-target%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

Chat program with C++ and SFML

Function to Return a JSON Like Objects Using VBA Collections and Arrays

Will my employers contract hold up in court?