【问题标题】:Find the shortest distance in hashmap在 hashmap 中找到最短距离
【发布时间】:2021-09-09 13:35:34
【问题描述】:

我正在尝试从谷歌示例面试中解决算法。

我们有 5 个街区。每个街区都可以有健身房、商店或商店,或者有两个或全部。 我们必须找到与所有物体距离最小的块。 (可以是伪代码或任何语言)

        val blocks1 = hashMapOf(
            "gym" to false,
            "school" to true,
            "store" to false,
        )
        val blocks2 = hashMapOf(
            "gym" to true,
            "school" to false,
            "store" to false,
        )
        val blocks3 = hashMapOf(
            "gym" to true,
            "school" to true,
            "store" to false,
        )
        val blocks4 = hashMapOf(
            "gym" to false,
            "school" to true,
            "store" to false,
        )
        val blocks5 = hashMapOf(
            "gym" to false,
            "school" to true,
            "store" to true,
        )

答案是第 4 块,因为我们有 1 步到健身房、1 步到商店和 0 步到学校

Whole example interview, it is 1st question from this video

在我看来,他们在此视频上所做的一切毫无意义,但我没有自己的解决方案。

有人可以给我一些解决方法吗? 我应该做哪些步骤? 也许我应该对已经存在的算法使用特殊算法?

【问题讨论】:

    标签: algorithm sorting hashmap distance graph-algorithm


    【解决方案1】:

    扫描前后距离。做前面时,在前面的距离上加 1,或者如果存在建筑物,则将距离设置为零。如果建筑物存在,则返回时将距离设置为零,否则将距离设置为前一个加一。

    距离最短者获胜。

    完全未经测试的代码

    enum building { gym, school, store, Last };
    std::vector<std::array<int, Last>> dist;
    dist.resize(blocks.size()+1);
    dist[0] = { MAXINT, MAXINT, MAXINT> };
    // forward scan
    unsigned block = 0;
    for (auto & build : blocks) {
      for (auto idx = gym; gym != Last; idx++) {
         if (build[idx])
           dist[block][idx]= 0;
         if (dist[block][idx] != MAXINT)
           dist[block+1][idx] = dist[block][idx]+1;
      }
    }
    
    // backward scan
    block = blocks.size()-1;
    int bestblock = 0;
    int bestsum = MAXINT;
    for (auto it = blocks.rbegin(); it != std::next(blocks.rend()): it++) {
      int sum = 0;
      for (auto idx = gym; gym != Last; idx++) {
         auto build = it[idx];
         if (build)
           dist[block][idx] = 0;
         else
           dist[block][idx] = std::min(dist[block+1][idx]+1, dist[block][building]);
         sum += dist[block][idx];
      }
      if (sum < bestsum) {
        bestsum = sum;
        bestblock = block;
      }
      block--;
    }
    
    std::cout << "Best block = " << bestblock << std::endl;
    

    【讨论】:

      【解决方案2】:

      目标是将复杂度从 N*N 降低到 N。希望下表有助于阐明算法。

      【讨论】:

        【解决方案3】:
        FUNCTION Has( B, A )    // true if block B has amenity A
           IF B does not exist
               RETURN FALSE
           IF B has A
               RETURN TRUE
           RETURN FALSE
        
        FUNCTION Distance( B, A )   // Distance from block B to nearest amenity A
           FOR D = 0, 1, 2, 3, ...
           IF Has( B+D, A )
              RETURN D
           IF Has( B-D, A )
              RETURN D
           IF D > number of blocks
              OUTPUT Amenity A is nowhere to be found
              STOP
        
        BESTB = -1           // block with best score so far
        BESTSCORE = -1       // best score so far
        LOOP B over blocks
           S = 0             // score for block B
           LOOP A over gym, school, store
               S = S + Distance( B, A )
           IF S == 0
              OUTPUT B
              STOP
           IF S < BESTSCORE
              BESTB = B
              BESTSCORE = S
        OUTPUT BESTB
        STOP
        
        
        
            
        

        【讨论】:

        • 什么是 Bestb ?你能写出类似 cmets 的东西吗?我的大脑无法处理它,我整周都在努力解决它
        • BESTB 是目前得分最高的区块
        【解决方案4】:

        考虑到给定的示例,我们需要计算块距离值的5*5 矩阵,例如A,其中A[i][j]ij 之间的距离。 如果满足两个条件中的任何一个,则此距离为 0:

        • 两个街区都没有便利设施(在这种情况下,距离毫无意义)
        • 两个街区都有便利设施(在这种情况下,显然是 0,因为不需要旅行)

        否则, 距离 = ij 之间的距离 = abs(i-j)

        这里需要注意的是这个矩阵是对称的,所以你可以简单地循环遍历矩阵的下半部分,所以本质上,不是循环通过5*5 = 25,而是通过5*(5-1)/2 = 10迭代计算距离.

        下面的 Python 代码就是这样做的 -

        import sys
        
        blocks = [{'gym': False, 'school': True, 'store': False},
                  {'gym': True, 'school': False, 'store': False},
                  {'gym': True, 'school': True, 'store': False},
                  {'gym': False, 'school': True, 'store': False},
                  {'gym': False, 'school': True, 'store': True}]
        
        reqs = ['gym', 'school', 'store']
        
        q = len(blocks)
        
        min_dist = sys.maxsize
        block_idx = -1
        
        for col in range(q-1):
            for row in range(col+1, q):
                row_b = blocks[row]
                col_b = blocks[col]
        
                dist = 0
                for req in reqs:
                    if row_b[req] == col_b[req]:
                        dist += 0
                    else:
                        dist += abs(row-col)
        
                if dist < min_dist:
                    min_dist = dist
                    block_idx = row
        
                print(f"({row}, {col}):\t{dist}")
        
        print(f"Output block index: {block_idx}")
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-05-08
          • 1970-01-01
          • 1970-01-01
          • 2010-10-25
          相关资源
          最近更新 更多