如何处理三和的角落案件?

时间:2016-06-29 15:14:33

标签: c# algorithm

我为3-sum提供了以下解决方案。我使用bin搜索来查找数组中所有唯一的三元组,它们总和为零。

public List<List<int>> ThreeSum(int[] nums)
{
    Array.Sort(nums);
    var res = new List<List<int>>();
    for(int i = 0; i < nums.Length; ++i)
    {
        for(int j = i+1; j < nums.Length; ++j)
        {
            if(nums[i] == nums[j]) { ++i; }

            int c = Array.BinarySearch(nums, -nums[i] - nums[j]);
            if(c > j)
            {
                res.Add(new List<int> { nums[i], nums[j], nums[c] });
            }
        }
    }

    return res;
}

它工作正常,但在输入时我不知道如何修复错误:

[0,0,0][0,0,0,0]

输入: [0,0,0]

输出: []

预期: [[0,0,0]]

1 个答案:

答案 0 :(得分:0)

<强>更新

  1. 尝试重载版本的Array.BinarySearch,它获取感兴趣范围内的元素的索引和元素的长度。即你需要在仅位于第j个元素之后的数组nums中找到这样的元素
  2. 删除if(nums[i] == nums[j]) { ++i; }行。它在角落案件中几乎没有任何作用
  3. ij更新为相应循环中下一个非等重元素。

    public class Program
    {
        static public List<List<int>> ThreeSum(int[] nums)
        {
            Array.Sort(nums);
            var res = new List<List<int>>();
            for (int i = 0; i < nums.Length; ++i)
            {
                for (int j = i + 1; j < nums.Length; ++j)
                {
                    int c = Array.BinarySearch(nums, j + 1, nums.Length - j - 1, -nums[i] - nums[j]);
    
                    if (c > j)
                    {
                        res.Add(new List<int> { nums[i], nums[j], nums[c] });
                    }
                    while (j < nums.Length - 1 && nums[j] == nums[j + 1])
                        j++;
                }
                while (i < nums.Length - 1 && nums[i] == nums[i + 1])
                    i++;
            }
    
            return res;
        }
    
        static public void printThreeSum(List<List<int>> list)
        {
            foreach (var item in list)
            {
                foreach (var t in item)
                {
                    Console.Write(t.ToString() + " ");
                }
                Console.Write("\n");
            }
            Console.Write("\n");
        }
    
        static void Main(string[] args)
        {
            printThreeSum(ThreeSum(new int[] { 0, 0, 0 }));
            printThreeSum(ThreeSum(new int[] { 0, 0, 0, 0 }));
            printThreeSum(ThreeSum(new int[] { 0, 0, 0, 0, 0 }));
            printThreeSum(ThreeSum(new int[] { -1, -1, 2 }));
            printThreeSum(ThreeSum(new int[] { -1, -1, -1, -1, 2, 2, 2 }));
            printThreeSum(ThreeSum(new int[] { -2, -1, -1, 1, 1, 1, 1 }));
            printThreeSum(ThreeSum(new int[] { -2, -1, 0, 1, 2 }));
        }
    }
    
  4. 输出:

    0 0 0
    
    0 0 0
    
    0 0 0
    
    -1 -1 2
    
    -1 -1 2
    
    -2 1 1
    
    -2 0 2
    -1 0 1
    

    P.S。我不是这个解决方案的粉丝,因为它是O(N ^ 2 * log(N)),其中该任务可以用O(N ^ 2)求解。我只想尽可能少地纠正你的代码