【问题标题】:TwoSum and BinarySearchTree in testdome.com; How to solve the warning message: Performance test?testdome.com 中的 TwoSum 和 BinarySearchTree;如何解决警告信息:性能测试?
【发布时间】:2021-01-16 09:03:01
【问题描述】:

我正在尝试解决 testdome.com 中的 C# 编程问题,但我发现了有关性能的问题。如何解决?

二叉搜索树

using System;

public class Node
{
    public int Value { get; set; }

    public Node Left { get; set; }

    public Node Right { get; set; }

    public Node(int value, Node left, Node right)
    {
        Value = value;
        Left = left;
        Right = right;
    }
}

public class BinarySearchTree
{
    public static bool Contains(Node root, int value)
    {
        Console.WriteLine("value=" + value);
        if(root == null)
            return false;
        else if(root.Value == value)
            return true;
        else if(root.Value != value)
        {
            return Contains(root.Left, value) | Contains(root.Right, value);
        }
        return false;
    }

    public static void Main(string[] args)
    {
        Node n1 = new Node(1, null, null);
        Node n3 = new Node(3, null, null);
        Node n2 = new Node(2, n1, n3);

        Console.WriteLine(Contains(n2, 3));
    }
}

Performance test on a large tree: Memory limit exceeded

https://www.testdome.com/for-developers/solve-question/7482

TwoSum

using System;
using System.Collections.Generic;

class TwoSum
{
    public static Tuple<int, int> FindTwoSum(IList<int> list, int sum)
    {
        for(int ctr1=0; ctr1<list.Count; ctr1++)
        {
            for(int ctr2=0; ctr2<list.Count; ctr2++)
            {
                if ((ctr1 != ctr2) && (list[ctr1]+list[ctr2] == sum))
                    return new Tuple<int, int>(ctr1, ctr2);
            }
        }
        return null;
    }

    public static void Main(string[] args)
    {
        Tuple<int, int> indices = FindTwoSum(new List<int>() { 1, 3, 5, 7, 9 }, 12);
        Console.WriteLine(indices.Item1 + " " + indices.Item2);
    }
}

Performance test with a large number of elements: Time limit exceeded

https://www.testdome.com/for-developers/solve-question/8125

【问题讨论】:

    标签: c#


    【解决方案1】:

    对于二叉搜索树,testdome.com 提供了一个提示“如果正在搜索的值小于节点的值,则可以忽略右子树。”这将内存消耗减少了一半。

    public static bool Contains(Node root, int value) {
        Console.WriteLine("value=" + value);
        if (root == null) {
            return false;
        }
        else if (value == root.Value) {
            return true; 
        } 
        else if (value < root.Value) {
            // Hint 2: If a value being searched for is smaller than the value of the node, 
            // then the right subtree can be ignored.
            return Contains(root.Left, value);
        }
        else {
            return Contains(root.Right, value);
        }
        return false;
    }
    

    对于 TwoSum,如果我们假设输入数组中的值是唯一的,我们可以使用字典按其值查找索引(在 O(1) 时间内)。这与提示“字典可用于存储预先计算的值,这可能允许具有 O(N) 复杂度的解决方案”有关。

    // Write a function that, when passed a list and a target sum, 
    // returns, efficiently with respect to time used, 
    // two distinct zero-based indices of any two of the numbers, 
    // whose sum is equal to the target sum. 
    // If there are no two numbers, the function should return null.
    public static Tuple<int, int> FindTwoSum(IList<int> list, int sum) {
    
        if (list.Count < 2) {
            return null;
        }
        
        // Hint 2: A dictionary can be used to store pre-calculated values,
        // this may allow a solution with O(N) complexity.
        var indexByValue = new Dictionary<int, int>();
        for (var i = 0; i < list.Count; i++) {
            var value = list[i];
            // ensure that the values used as keys are unique
            // this is OK because we only have to return any tuple matching the sum,
            // therefore we can ignore any duplicate values
            if (!indexByValue.ContainsKey(value)) {
                indexByValue.Add(value, i);
            }
        }
        
        for (var j = 0; j < list.Count; j++) {
            var remainder = sum - list[j];
            if (indexByValue.ContainsKey(remainder)) {
                return new Tuple<int, int> (j, indexByValue[remainder]);
            }
        }
        
        return null;
    }
    

    【讨论】:

    • 嗨,Georg Patscheider,谢谢。
    • 我回来+1,因为我以前不能
    【解决方案2】:

    解决问题的更简单方法。上面的答案都不错,但是觉得可以更快的找到想要的结果。

    public static Tuple<int, int> FindTwoSum(IList<int> list, int sum)
    {
        if (list.Count < 2) { return null; }
    
        foreach (int i in list)
        {
            int result = sum - i;
            if(list.Contains(result))
            {
                return new Tuple<int, int>(i, result);
            }
        }
    
        return null;
    }
    

    【讨论】:

    【解决方案3】:

    对于 TwoSum,我发现下面的链接可以 100% 通过 TestDome:寻找 JonnyT 的答案:

    TwoSum 100% Pass

    下面也是代码:

    PS:我只是提供这个来帮助别人,所以请投票给 JonnyT 的答案而不是我的 :)

    public static Tuple<int, int> FindTwoSum(IList<int> list, int sum)
    {
       HashSet<int> hs = new HashSet<int>();
       for (int i = 0; i < list.Count; i++)
       {
           var needed = sum - list[i];
           if (hs.Contains(needed))
           {
               return Tuple.Create(list.IndexOf(needed), i);
           }
           hs.Add(list[i]);                
       }
       return null;
    }
    
    public static void Main(string[] args)
    {
        Tuple<int, int> indices = FindTwoSum(new List<int>() { 3, 1, 5, 7, 5, 9 }, 10);
        if (indices != null)
        {
            Console.WriteLine(indices.Item1 + " " + indices.Item2);
        }
    }
    

    【讨论】:

      【解决方案4】:
      // This passes all tests
      
      public static bool Contains(Node root, int value)
      {        
      
          var result = false;
      
          if (root == null) return result;
      
          if (value == root.Value) 
          {
              result = true; 
          }
          else
          {
              if(value <= root.Value)
              {
                  if(Contains(root.Left, value))
                  {
                      result = true;
                  }                           
              }
              else
              {
                  return Contains(root.Right, value); 
              }                   
          }
      
          return result;
      
      }
      

      【讨论】:

        猜你喜欢
        • 2018-08-11
        • 1970-01-01
        • 2016-02-13
        • 1970-01-01
        • 1970-01-01
        • 2013-04-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多