繁体   English   中英

从列表中获取结果的 C# 问题<t> BinarySearch 在第一个和最后一个 position 中具有重复项</t>

[英]C# problems getting results from List<T> BinarySearch with duplicates in the first and last position

对于最简单的 LeetCode 问题 TwoSums,我正在尝试不同的实现。 我有各种其他方法可以使用 indexof、字典搜索、蛮力等方法正常工作......到目前为止,我最好的方法是使用 List.IndexOf 的 98.67%

我正在尝试使用 BinarySearch 实现一个版本以进行比较。 它通过了大多数测试,但在需要对第一个和最后一个 position 中的重复项求和并且列表长度为 gt 2 时似乎失败了。我确信还有其他失败条件,但我无法超越这个。

单步执行代码时,尽管从 i+1 索引位置开始,当最后一个和第一个是相同的值时,它返回一个负数而不是索引。

我必须遗漏一些明显的东西,但由于某种原因我没有看到它。 也许我只是误解了 BinarySearch 如何处理索引和长度。

这些通过:
{ 0, 2, 3 } 目标 3
结果:{0, 2}

{ 3, 3 } 目标 6
结果:{ 0, 1 }

{ 0, 2, 0, 3 } 目标 0
结果:{ 0, 2 }

这些失败:
{ 0, 2, 0 } 目标 0
预期:{ 0, 2 } 结果:null

{ 1, 4, 1 } 目标 2
预期:{ 0, 2 }
结果:null

在我处理这些问题时,代码示例现在很冗长。 我稍后会最小化它。

offset 用于在高于 i 的索引处开始搜索
子集长度用于防止搜索长度超出范围
n > i 只是一个健全性检查,以确保在返回有效结果之前 n 是比 i 更高的索引值

public int[] TwoSum(int[] nums, int target)
{
    List<int> numList = new List<int>(nums);
    for (int i = 0; i < nums.Length; i++)
    {
        int offset = i + 1; 
        int subsetLength = nums.Length - offset; 
        int searchNum = target - nums[i]; 
        int n = numList.BinarySearch(offset, subsetLength, searchNum, null);
        if (n > i) 
            return new int[] { i, n };
    }
    return null;
}

是的,当您检查两个项目时,您有一个特殊情况target / 2 + target / 2 == target ,每个项目都是target / 2

public int[] TwoSum(int[] nums, int target) {
  // Comment out if nums is already sorted
  Array.Sort(nums);

  for (int i = 0; i < nums.Length; ++i) {
    int item = nums[i];
    int toFind = target - item;

    if (toFind < nums[i])
      break;

    int index = Array.BinarySearch(nums, toFind);

    if (index >= 0) {
      if (toFind == item) {
        // Special case: two equal numbers: target / 2 + target / 2 = target
        if (i < nums.Length - 1 && nums[i] == nums[i + 1])
          return new int[] { i, i + 1 };

        break;
      }
      else
        return new int[] { i, index };
    }
  }

  return new int[] { -1, -1 };
} 

只需在搜索之前对列表进行排序:

public int[] TwoSum(int[] nums, int target)
    {
        List<int> numList = new List<int>(nums);

        numList.Sort();

        for (int i = 0; i < nums.Length; i++)
        {
            int offset = i + 1;
            int subsetLength = nums.Length - offset;
            int searchNum = target - nums[i];
            int n = numList.BinarySearch(offset, subsetLength, searchNum, null);
            if (n > i)
                return new int[] { i, n };
        }
        return null;
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM