我目前正在研究一个称为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);
}
}
答案 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)
您的实现假定列表已排序,因为在第二步中,如果您检查start
和end
的总和是否小于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
开始,在下一个元素处查看索引0
和end
。如果与目标匹配,则返回结果。如果不是,它将递增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]