暴力搜索-堆棋子

https://www.nowcoder.com/practice/27f3672f17f94a289f3de86b69f8a25b?tpId=90&tqId=30785&tPage=1&rp=1&ru=/ta/2018test&qru=/ta/2018test/question-ranking

大致题目就是:

在坐标系上有n个点,移动所有这些点到一个点上的最短距离,只能上下左右走。首先我们要确定最终走向哪些点,可能所计算出来的步数是最短的。

首先我们简化问题,假设这些点只在坐标轴上。这些点只能左右移动,有一个规律就是最终位置一定在这些点中的某一个点(这里证明过程省略)

那么我们就可以用暴力搜索了

最外层就是可能的最终点,计算所有其他点到这个点的距离,求和,再取最小值,就能得到最短步数了。(这里排了一层序是为了计算题目所要求的最终节点数i个这样的要求)

public static int[] minOps(int size,int[] x){
        int[] res=new int[size];
        PriorityQueue<Integer> que=new PriorityQueue<>();
        Arrays.fill(res, Integer.MAX_VALUE);
        for(int i=0;i<size;i++) {
            for(int j=0;j<size;j++) {
                que.add(Math.abs(x[i]-x[j]));        
            }
            int sum=0;
            int resI=0;
            while(!que.isEmpty()) {
                int temp=que.poll();
                sum+=temp;
                res[resI]=Math.min(res[resI],sum);
                resI++;
            }
        }
        return res;
}

在二维的情况下,最终节点会不一样,因为不可能刚好x轴和y轴的最终节点刚好对应上,所以除了原先这些节点以外,我们还加入了,某一个节点x坐标和另外节点y坐标对应的这样的其他节点,这些节点也是可能成为最终节点的,其他的思想和一维情况是一样的。

public static int[] minOPs(int size, int[] x, int[] y) {
          int[] res = new int[size];
          Arrays.fill(res, Integer.MAX_VALUE);
          PriorityQueue<Integer> pq = new PriorityQueue<>();
          for (int i = 0; i < size; i++) {
              for (int j = 0; j < size; j++) {
                  for (int k = 0; k < size; k++) {
                      pq.add(Math.abs(x[k] - x[i]) + Math.abs(y[k] - y[j]));
                  }
                  int resI = 0;
                  int sum = 0;
                  while (!pq.isEmpty()) {
                      sum += pq.poll();
                      res[resI] = Math.min(res[resI], sum);
                      resI++;
                  }
              }
          }
          return res;
      }

同样的就算三维,思想还是不变的。

posted @ 2019-05-05 13:51  LeeJuly  阅读(146)  评论(0)    收藏  举报