【问题标题】:Figure out max number of consecutive seats找出最大连续座位数
【发布时间】:2020-03-18 19:42:34
【问题描述】:

我有一个面试官让我用 c# 编写一个程序来计算一个场地可以连续坐的最多 4 个成员家庭的数量,考虑到 4 个成员必须连续坐在一排,以下上下文:

  • N 表示可用的行数。
  • 列从字母“A”到“K”标记,故意省略字母“i”(换句话说,{A,B,C,D,E,F,G,H,J,K })
  • M 代表预留座位列表

快速示例:

N = 2
M = {"1A","2F","1C"}
Solution = 3

在表示中,您可以看到,在预订和给定大小的情况下,只有三个 4 口之家可以按顺序就座。

你会如何解决这个问题?可以不使用for循环吗? (Linq 解决方案)

在尝试处理保留数组时,我在 for 循环中搞混了:我的想法是获取一行具有的所有保留,但是我真的不知道如何处理字母(直接转换从字母到数字是行不通的,因为缺少“I”),而且无论如何您都需要字母来定位保留的位置。

任何关于如何解决这个问题的方法或见解都会很好。 提前致谢!

【问题讨论】:

  • 字母到索引的转换可以使用Dictionary<char, int> 或者如果您想要使用char[] 来完成,其中字母的索引是行中的索引。
  • 希望面试官不在身边
  • 查询具有bbbbbbbb(8 个空格)、bbbbx && xbbbb(2 乘以 4 个空格)和bbbb(4 个空格)的字符串。如果您使用查询,这些组合应该给出结果

标签: c# algorithm linq logic


【解决方案1】:

这是另一个实现。

我还试图解释为什么会做某些事情。

祝你好运。

    private static int GetNumberOfAvailablePlacesForAFamilyOfFour(int numberOfRows, string[] reservedSeats)
    {
        // By just declaring the column names as a string of the characters
        // we can query the column index by colulmnNames.IndexOf(char)
        string columnNames = "ABCDEFGHJK";


        // Here we transform the reserved seats to a matrix
        // 1A 2F 1C becomes
        // reservedSeatMatrix[0] = [0, 2] -> meaning row 1 and columns A and C, indexes 0 and 2
        // reservedSeatMatrix[1] = [5] -> meaning row 2 and column F, index 5
        List<List<int>> reservedSeatMatrix = new List<List<int>>();

        for (int row = 0; row < numberOfRows; row++)
        {
            reservedSeatMatrix.Add(new List<int>());
        }

        foreach (string reservedSeat in reservedSeats)
        {
            int seatRow = Convert.ToInt32(reservedSeat.Substring(0, reservedSeat.Length - 1));
            int seatColumn = columnNames.IndexOf(reservedSeat[reservedSeat.Length - 1]);
            reservedSeatMatrix[seatRow - 1].Add(seatColumn);
        }

        // Then comes the evaluation.
        // Which is simple enough to read.
        int numberOfAvailablePlacesForAFamilyOfFour = 0;

        for (int row = 0; row < numberOfRows; row++)
        {
            // Reset the number of consecutive seats at the beginning of a new row
            int numberOfConsecutiveEmptySeats = 0;

            for (int column = 0; column < columnNames.Length; column++)
            {
                if (reservedSeatMatrix[row].Contains(column))
                {
                    // reset when a reserved seat is reached
                    numberOfConsecutiveEmptySeats = 0;
                    continue;
                }
                numberOfConsecutiveEmptySeats++;
                if(numberOfConsecutiveEmptySeats == 4)
                {
                    numberOfAvailablePlacesForAFamilyOfFour++;
                    numberOfConsecutiveEmptySeats = 0;
                }
            }
        }

        return numberOfAvailablePlacesForAFamilyOfFour;
    }


    static void Main(string[] args)
    {
        int familyPlans = GetNumberOfAvailablePlacesForAFamilyOfFour(2, new string[] { "1A", "2F", "1C" });
    }

【讨论】:

    【解决方案2】:

    祝你面试顺利

    与往常一样,系统会询问您如何改进这一点?所以你会考虑复杂的东西,比如 O(N)、O(wtf)。

    底层实现总是需要forforeach。只是重要,永远不要在循环中做不必要的事情。例如,如果一排只剩下 3 个座位,则无需继续在那一排寻找,因为找不到任何座位。

    这可能有点帮助:

        var n = 2;
        var m = new string[] { "1A", "2F", "1C" };
    
        // We use 2 dimension bool array here. If it is memory constraint, we can use BitArray.
        var seats = new bool[n, 10];
        // If you just need the count, you don't need a list. This is for returning more information.
        var results = new List<object>();
    
        // Set reservations.
        foreach (var r in m)
        {
            var row = r[0] - '1';
            // If it's after 'H', then calculate index based on 'J'.
            // 8 is index of J.
            var col = r[1] > 'H' ? (8 + r[1] - 'J') : r[1] - 'A';
            seats[row, col] = true;
        }
    
        // Now you should all reserved seats marked as true.
        // This is O(N*M) where N is number of rows, M is number of columns.
        for (int row = 0; row < n; row++)
        {
            int start = -1;
            int length = 0;
    
            for (int col = 0; col < 10; col++)
            {
                if (start < 0)
                {
                    if (!seats[row, col])
                    {
                        // If there's no consecutive seats has started, and current seat is available, let's start!
                        start = col;
                        length = 1;
                    }
                }
                else
                {
                    // If have started, check if we could have 4 seats.
                    if (!seats[row, col])
                    {
                        length++;
                        if (length == 4)
                        {
                            results.Add(new { row, start });
    
                            start = -1;
                            length = 0;
                        }
                    }
                    else
                    {
                        // // We won't be able to reach 4 seats, so reset
                        start = -1;
                        length = 0;
                    }
                }
    
                if (start < 0 && col > 6)
                {
                    // We are on column H now (only have 3 seats left), and we do not have a consecutive sequence started yet,
                    // we won't be able to make it, so break and continue next row.
                    break;
                }
            }
        }
    
        var solution = results.Count;
    

    LINQ、forforeach 是类似的东西。您可以将上述内容包装到自定义迭代器中,例如:

    class ConsecutiveEnumerator : IEnumerable
    {
        public IEnumerator GetEnumerator()
        {
        }
    }
    

    然后你就可以开始使用 LINQ了。

    【讨论】:

      【解决方案3】:

      如果您以对开发人员来说简单的格式表示您的矩阵,会更容易。您可以通过字典或手动执行不那么复杂的映射来完成它。无论如何,这将计算免费连续座位的数量:

          public static void Main(string[] args)
          {
              var count = 0;//total count
              var N = 2; //rows
              var M = 10; //columns
              var familySize = 4;
              var matrix = new []{Tuple.Create(0,0),Tuple.Create(1,5), Tuple.Create(0,2)}.OrderBy(x=> x.Item1).ThenBy(x=> x.Item2).GroupBy(x=> x.Item1, x=> x.Item2);
              foreach(var row in matrix)
              {
                  var prevColumn = -1;
                  var currColumn = 0;
                  var free = 0;
                  var div = 0;
      
                  //Instead of enumerating entire matrix, we just calculate intervals in between reserved seats. 
                  //Then we divide them by family size to know how many families can be contained within
                  foreach(var column in row)
                  {
                      currColumn = column;
                      free = (currColumn - prevColumn - 1)/familySize;
                      count += free;
                      prevColumn = currColumn;
                  }
                  currColumn = M;
                  free = (currColumn - prevColumn - 1)/familySize;
                  count += free;
              }
      
      
              Console.WriteLine("Result: {0}", count);
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-02-04
        • 1970-01-01
        • 2021-04-02
        • 2013-09-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多