HashSet的两次求和问题不适用于重复项

时间:2019-06-14 00:52:15

标签: c# algorithm big-o hashset

我正在做一个作业,其中我必须找到具有平均/最佳O(n)或线性运行时复杂度的数字对,总计为“ x”。我不能使用蛮力,因为它会增加复杂性。

我正在使用HashSet并正在使用contains方法,我正在检查是否可以找到(x-array [i])并进行打印。但是包含整个HashSet的方法检查,我想在每次迭代的第“ i”个位置之后从该位置开始搜索。另外,我无法对它们进行排序,因为我必须按照它们在输入数组中出现的顺序打印它们。

          if (hSet.Contains(x - array[i]))
             {
                 Console.Write("(" + array[i] + "," + (x - array[i]) + ")");
                        hSet.Add(array[i]);

                }
             }

使用输入数组{1,6,3,2,5,5,7,8,4,8,2,5,9,9,1,};

我的输出(1,9)(6,4)(3,7)(2,8)(5,5)(5,5)(7,3)(8,2)(4,6) (8,2)(2,8)(5,5)(9,1)(9,1)

预期输出:(1,9),(1,9),(6,4),(3,7),(2,8),(2,8),(5,5),(5 ,5),(5,5),(8,2),(8,2),(9,1),(9,1)

2 个答案:

答案 0 :(得分:1)

此代码可以满足您对O(n)复杂度的要求(大多数情况下)。使用Dictionary,而不是HashSet

  • 首先,从数组构建字典,键为项目,值为项目的计数。

  • 在那之后,遍历所有项目,并用字典检查它并产生输出。还要减少“字典”中此项的数量,以免日后不必要的输出。

代码如下:

using System;
using System.Collections.Generic;

class MainClass {
    public static void Main (string[] args) {
        int[] array = { 1, 6, 3, 2, 5, 5, 7, 8, 4, 8, 2, 5, 9, 9, 1 };
        int x = 10;
        // build dictionary
        Dictionary<int,int> dict = new   Dictionary<int,int>();
        for(int i=0; i< array.Length; i+=1){
            if(dict.ContainsKey(array[i])){
                dict[array[i]] += 1;
            } else {
                dict.Add(array[i], 1);
            }
        }
        // using dictionary
        for(int i=0; i< array.Length; i+=1){
            if(dict.ContainsKey(x - array[i])) {
                int count = dict[x - array[i]];
                if(x - array[i] == array[i]){
                    count -= 1;
                }

                for(int j = 0; j< count; j+=1 ) {
                    Console.Write("(" + array[i] + "," + (x - array[i]) + ")");
                }

                dict[array[i]] -=1;
                if(dict[array[i]] == 0){
                    dict.Remove(array[i]);
                }
            }
        }
        Console.WriteLine();
    }
}

答案 1 :(得分:0)

这是我使用Dictionary的简单解决方案。 O(n)时间。

namespace TwoSumLeetCode
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] arr = { 1, 2, 7, 9, 4 };

            int target = 13;

            Console.WriteLine(TwoSum(arr, target));

            Console.ReadLine();
        }

        // assuming array and target are provided.
        public static int[] TwoSum(int[] nums, int target)
        {
            Dictionary<int, int> dict = new Dictionary<int, int>();
            for (int i = 0; i < nums.Length(); ++i)
            {
                if (dict.ContainsKey(target - nums[i]))
                {
                    return new int[] { dict[target - nums[i]], i };
                }

                else
                {
                    dict[nums[i]] = i;
                }
            }

            return null;
        }
    }
}