算法改进

时间:2013-12-24 05:57:55

标签: c# algorithm

我的面试任务是:

找到一个满足条件的数组项:删除它后,其余项的乘法将是最高的。 例如:-5,-3,-1,4,6 => -1

我的解决方案被认为是非常优化的。 你能否就算法改进提出一些建议?

我的解决方案是

public int FindRequiredValue(int[] IntArray)
    {
        try
        {
            Array.Sort(IntArray);

            var first = IntArray.First();
            var last = IntArray.Last();

            if (first >= 0)
                return first;
            else
                if (last < 0)
                    return (IsEven(IntArray.Count()) ? first : last);
                else
                {
                    if (last == 0)
                    {
                        var lastindex = IntArray.Count() - 1;
                        if (IntArray[lastindex - 1] == 0)
                            return first;
                        else
                            return IsEven(lastindex) ? 0 : first;
                    }
                    else
                    {
                        var firstpositiveindex = IntArray.Select((x, i) => new { element = x, index = i }).First(y => (y.element > 0)).index;

                        if (IntArray[firstpositiveindex - 1] < 0)
                            return IsEven(firstpositiveindex) ? IntArray[firstpositiveindex] : IntArray[firstpositiveindex - 1];
                        else
                            if (IntArray[firstpositiveindex - 2] < 0)
                                return IsEven(firstpositiveindex - 1) ? 0 : first;
                            else
                                return first;
                    }
                }
        }
        catch (Exception ex)
        {
            throw;
        }
    }

请注意,所有非空检查都会溢出e.t.c.在调用函数之前正在检查。

更新: 可能的方法:排序等,循环等;还有其他想法吗?

2 个答案:

答案 0 :(得分:5)

无需 排序数组,这需要 O(n * log(n))复杂度; 你可以用 O(n)解决方案完成。这就是为什么,恕我直言,你的代码次优。 可能的实施:

public int FindRequiredValue(int[] value) {
  if (Object.ReferenceEquals(null, value))
    throw new ArgumentNullException("value");
  else if (value.Length <= 0)
    throw new ArgumentException("Empty arrays can't be proceeded.", "value");

  // Algorithm:
  // if the array contains odd negative numbers print out the maximum among them:
  //   {-1, -2, -3, 4, 5} => -1
  // if the array contains even negative numbers print out the smallest non-negative one:
  //   {-1, -2, 4, 5} => 4
  // if array contains even negative numbers and no non-negative numbers print out the
  // smallest negative one 
  //   {-1, -2, -3, -4} => -4

  int max_Negative = 0;
  int min_Negative = 0;
  int min_NonNegative = -1;
  int negativeCount = 0;

  foreach (int v in value) {
    if (v < 0) {
      negativeCount += 1;

      if ((v > max_Negative) || (max_Negative == 0))
        max_Negative = v;

      if ((v < min_Negative) || (min_Negative == 0))
        min_Negative = v;  
    }
    else {
      if ((v < min_NonNegative) || (min_NonNegative == -1))
        min_NonNegative = v; 
    }  
  }

  if ((negativeCount % 2) == 1)
    return max_Negative;
  else if (min_NonNegative != -1)
    return min_NonNegative;
  else
    return min_Negative; 
}

答案 1 :(得分:0)

在这个问题中,如果存在奇数个负整数,您将要删除最小的(绝对值)负整数,如果存在偶数个负整数,则要删除最小的正整数。 (零计为正数)

所以迭代一次数组并跟踪:
1.绝对值最小的负整数。
2.绝对值最低的正整数 3.负整数的数量。

迭代后,相应地删除。

复杂性:时间为O(N),空间为O(1)。