如何使TwoSum方法处理不按顺序排列的数字?

时间:2019-10-09 09:26:11

标签: c# arrays

我目前正在研究一个称为TwoSums的LeetCode问题。

它要求我:

  

给出一个整数数组,返回两个数字的索引,以使它们加起来成为一个特定的目标。

     

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

我的代码可用于不同长度的数组。但是,我发现,如果数字不正确,则会给出错误的答案。

我的测试用例是[3,2,4]目标数量= 6。

public class Solution {

    public int[] TwoSum(int[] nums, int target) 
    {        
        int[] ret = new int[2]; 
        int start = 0
        int end = nums.Length - 1;

        while(start < end)
        {
           if (nums[start] + nums[end] == target)
           {
              ret[0] = start; 
              ret[1] = end;
              break; 
           }
           else if(nums[start] + nums[end] < target)
           {
              start++;
           }
           else
           {
              end--; 
           }
       }return(ret); 
   }    
}

5 个答案:

答案 0 :(得分:2)

您可以使用2个嵌套循环。 :

Dim OutApp As Object
Dim OutMail As Object
Dim strbody As String
Dim WS As Worksheet

If ActiveWorkbook.Path <> "" Then
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
Set WS = Sheets("Ingave")

strbody = "<font size=""3"" face=""Calibri"">" & _
"Beste Collega,<br><br>" & _
"Een nieuwe retour zending registratie werd aangemaakt met urgentie: <B>" & WS.Cells(6, 3).Value & "</B>.<br>" & _
"Het pakket nummer is <B>" & WS.Cells(22, 3).Value & "</B>.<br><B> " & _
"</B><br><br>In geval van vragen gelieve contact op te nemen." & _
"<br><br> Met vriendelijke groeten, </font>"
On Error Resume Next

With OutMail
.to = "xxx@yyy"
.CC = ""
.BCC = ""
.Subject = "Nieuwe registratie retour pakket "
.HTMLBody = strbody
.Display   'or use .Send
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
Else
MsgBox "U moet de file eerst opslaan voor u verder kan gaan."
End If

答案 1 :(得分:2)

这是一个简单的蛮力解决方案,它检查每对数字。时间复杂度为O(n ^ 2):

public int[] TwoSum(int[] nums, int target)
{
    for (int i = 0; i < nums.Length - 1; i++)
    {
        for (int j = i + 1; j < nums.Length; j++)
        {
            if (nums[i] + nums[j] == target)
            {
                return new[] { i, j };  
            }
        }
    }

    throw new Exception("Solution not found");
}

我们注意不要尝试任何一对以上-j总是始于i以上。

答案 2 :(得分:1)

您的实现假定列表已排序,因为在第二步中,如果您检查startend的总和是否小于target。试试这种方法:

public class Solution
{
    public int[] TwoSum(int[] nums, int target)
    {
        int[] ret = new int[2]; 

        if (nums.Length < 2)
            return ret;

        int start = 0;
        int end = 1;

        while (start < (nums.Length -1))
        {           
            if (nums[start] + nums[end] == target)
            {
                ret[0] = start; 
                ret[1] = end;
                break; 
            }

            if (end < nums.Length -1))
            {
                end++
            }
            else
            {
                start++;
                end = start + 1
            }
        }

        return ret; 
    }

}

它从start开始,在下一个元素处查看索引0end。如果与目标匹配,则返回结果。如果不是,它将递增end直到到达数组末尾。它将增加start并将end重设为start + 1,以再次查看下一个元素。依此类推,直到start到达最后一个元素。然后,它检查了所有组合。

答案 3 :(得分:1)

有很多方法可以解决此问题,但是最直接的方法(如其他答案所指出的)是嵌套循环。

在我再次读到你的问题之前,他们都错过了包括我自己在内的一切:

  

您可以假设每个输入都只有一个解决方案,

虽然看起来并不重要,但实际上给了我们一个小的优化:反向搜索。

对给定输入使用正向方法,进行了3​​次比较以找到答案:

[0, 1] => 3 + 2 != 6
[0, 2] => 3 + 4 != 6
[1, 2] => 2 + 4 == 6

对于每次通过外循环的次数,通过内循环的次数都会减少。除非答案中包含数组中的第一项,否则意味着您要进行的测试超出了需要。

如果我们反向搜索,则可以更快地从每个外部循环中消除配对:

static int[] TwoSums(int target, int[] array)
{
    for (int i1 = array.Length - 2; i1 >= 0; i1--)
    {
        int v1 = array[i1];
        for (int i2 = i1 + 1; i2 < array.Length; i2++)
        {
            if (v1 + array[i2] == target)
                return new[] { i1, i2 };
        }
    }
    return null;
}

这样,您的示例的顺序是:

[1, 2] => 2 + 4 == 6

这有点作弊,因为在这种情况下答案是最后一对。让我们尝试一些不同的东西并进行比较:

Array: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31]
Test value: 24

使用一些工具,我们可以看到循环运行了多少次。对于这种特殊情况,正向搜索在找到有效的反向搜索之前先进行22次比较,而反向仅进行11次比较。如果测试值为48(19 + 29),则数字为:正向= 49,反向= 5。

当然,如果答案包含前两个值之一,则数字会翻转。这是一场平均游戏。

答案 4 :(得分:0)

class Program
{
    static void Main(string[] args)
    {
        int[] indexes = GetSumIndexes(new int[] { 3, 2, 4 }, 6);
    }

    public static int[] GetSumIndexes(int[] numbers, int target)
    {
        for (int i = 0; i < numbers.Length; i++)
        {
            for (int j = 0; j < numbers.Length; j++)
            {
                if (i != j)
                {
                    if (numbers[i] + numbers[j] == target)
                    {
                        return new int[] { i, j };
                    }
                }
            }
        }
        return new int[] { };
    }
}

输出:

  

[1,2]


您可以在其他答案中找到的优化版本:

class Program
{
    static void Main(string[] args)
    {
        int[] indexes = GetSumIndexes(new int[] { 3, 2, 4 }, 6);
    }

    public static int[] GetSumIndexes(int[] numbers, int target)
    {
        for (int i = 0; i < numbers.Length; i++)
        {
            for (int j = i + 1; j < numbers.Length; j++)
            {
                if (numbers[i] + numbers[j] == target)
                {
                    return new int[] { i, j };
                }
            }
        }
        return new int[] { };
    }
}

输出:

  

[1,2]