【问题标题】:Find Maximum difference between two numbers in list using Bitwise AND使用按位与查找列表中两个数字之间的最大差
【发布时间】:2016-06-08 03:46:08
【问题描述】:

大家好,我正在解决一个问题:

给定一个集合 S = {1, 2, 3, ... N}。从集合 S 中找到两个整数 A 和 B,其中 (A

样本输入1:5 2,(其中n = 5,k = 2)=>输出:1,

示例输入 2:8 5,(其中 n = 8,k = 5)=> 输出:4

我编写了代码,这似乎工作正常。但我正在寻找更优化的解决方案。我目前正在使用两个 while 循环,我不确定是否可以简化为一个 while 或 for 循环。以下是我的功能:

static void Main(String[] args)
{
    string[] tokens_n = Console.ReadLine().Split(' ');
    int n = Convert.ToInt32(tokens_n[0]);
    int k = Convert.ToInt32(tokens_n[1]);
    int i = 1, maxDiff = 0;
    while (i < n)
    {
      int j = i + 1;
      while (j <= n)
      {
        int diff = i & j;
        if (diff < k)
        {
          if (diff > maxDiff)
          {
            maxDiff = diff;
          }
        }
        j++;
      }
      i++;
    }
    Console.WriteLine(maxDiff);
}

我找到了一个解决方案here,但这个问题似乎是关于在列表中找到两个任意数字的最大差异,而我需要循环所有组合以找到按位与值然后进行比较。

【问题讨论】:

  • 代码没问题。我会使用 For 循环而不是 while 循环。 For循环更容易理解,并且会减少代码行数。

标签: c# loops optimization bitwise-and


【解决方案1】:
int maxAnd = INT_MIN;
    for(int i = 1; i < k; i++) {
        for(int j = i + 1; j <= n; j++) {
            int currentAnd = i & j;
            if (currentAnd > maxAnd)
                maxAnd = currentAnd;
        }
    }
    cout << maxAnd << endl;

【讨论】:

  • 它在 O(kn) 时间内运行...比 O(n2) 好...我已经用 c++ 语言发布了
【解决方案2】:

从效率的角度来看,这可能没有更优化,但更具可读性。

    var list = new[] {1, 2, 3, 4, 5};
    var k = 2;

    var combinations = 
        from item1 in list
        from item2 in list
        where
            (item1 < item2) &&
            (item1 & item2) < k
        orderby item1 & item2 descending
        select new {item1, item2};

    Console
        .WriteLine(combinations.First());

【讨论】:

    【解决方案3】:

    事实证明,解决方案可以大大简化(根据我们检查的内容,而不是可读性)。因此,与其提供改进代码的方法 - 我可以针对原始需求提供新的解决方案

    void Main()
    {
        var n = 2;
        var k = 2;
    
        //Best solution is for k - 1 (that is, B = k - 1, and then we check all possible As)
        for (var i = k - 1; i > 0; i--)
        {
            int j;
            int index = 1;
            //The only possible A is when 
            //1. j <= n
            //2. j contains all the same bits as i since we identify that `i` is the possible solution, 
            //   and we are using bit-wise AND, we
            //So, here were looping while the number is the same as i, continually flipping bits on
            //Since we're shifting bits in, we can assume the first value != i is a solution, as we only care about j becoming too large
            while ((j = (i | index)) == i && j <= n)
                index = (index << 1) | 1;
    
            // If j <= n, and it contains all the bits of i, and i <= k - 1, then we have a solution
            if (j <= n)
            {
                Console.WriteLine($"i = {i}, j = {j}, Solution = {i & j}");
                return;
            }
        }
    
        if (n < 2 || k < 1)
            Console.WriteLine("No solution");
        else
            Console.WriteLine($"i = 1, j = 2, Solution = 0");
    } 
    

    这种方法可以让我们解决如下输入:

    var n = 24827492;
    var k = 2384972;
    

    对于低值,我们几乎尽可能快。

    【讨论】:

      猜你喜欢
      • 2012-03-08
      • 1970-01-01
      • 1970-01-01
      • 2015-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-26
      • 2014-01-12
      相关资源
      最近更新 更多