leetcode 296 题解(暴力破解)

今天朋友问了我一道leetcode第296题,于是我将自己对题目的拙见写了下来。  

(提前说明,暴力破解方法比较简单粗暴,时间和内存会消耗很大,如果需要更快更省的办法去解决这个问题的话,建议不用看这篇随笔了!)

题目分析:

  由题可知1. 输入的数据是一个由0和1 组成的二维数组            

          2.(一队人)两人或以上   -------->  说明值为1 的数据至少有两个    

       3.提供了一个公式 曼哈顿公式 ------->这大大降低了题目难度。

  根据题目析提供的输入和输出,假设碰面点 为P点(0,2) ,三个人的点分别是A(0,0) B(0,4) C(2,2) 三个点,根据曼哈顿公式

      AP距离  = |0-0|+|2-0|=2  BP距离  = |0-0|+|2-4|=2   CP距离  = |0-2|+|2-2|=2

  总的行走距离就为  distase = AP+BP+CP=2+2+2=6   

  题目难点:

      1.如何确定最佳碰面点  ?     

    答:由于万物皆可暴力,先标记值为1的点, 然后对二维数组的每一个的位置,进行距离运算 ,统计最小的值

      (我最初的想法是对值为0的位置运算,但测试数据告诉我,如果一个人不走,也有可能最小距离。 例 [{1,0,1,0,1}] 结果是4)

      2.初始的人数无法确定

    答:创建两个int数组,一个是每个人的x 坐标 ,一个是每个人的y坐标,进行距离运算的时候,只需遍历数组即可。

数据结构分析:

    由于输入的数据长度 无法确定  ---->  优先考虑使用 list 集合 存储

    由于 一个人代表的是一个坐标  有两个属性(x,y) -----> 考虑创建一个point 对象 存储到集合里

1 public class point {
2         public int x; 
3         public int y;
4         //构造方法
5         public point(int x, int y) {
6             this.x = x;
7             this.y = y;
8         }    
9

解题思路:

   1.声明两个集合,list1用来存储值为1的点  list2用来存储所有位置的点

        List<point> list1 = new  ArrayList<point>(); 
        List<point> list2 = new  ArrayList<point>();

   2.遍历数据,将数值放入对应集合  

        for(int i=0;i<arr.length;i++) {
            for(int j=0;j<arr[i].length;j++) {
                list2.add(new point(i,j));  //每个位置放到List2
                if(arr[i][j]==1) {  
                    list1.add(new point(i,j)); //值为1的点放入List1
                }    
            }
        }

   3,创建两个数组,分别代表每个人的  x位置数组 和y位置数组。并利用list1 集合给数组添加值

1         int x[] =new int[list1.size()]; //每个人的x位置
2         int y[] =new int[list1.size()];    //每个人都y位置
3         
4         for(int i=0;i<x.length;i++) {
5             x[i]=list1.get(i).x; //获取list1第i个点的x
6             y[i]=list1.get(i).y;//获取list1第i个点的y
7         }

   4.对每个点(list2的点)进行距离运算,并将所有结果放到一个mindis数组中

        int mindis[] = new  int[list2.size()];
        for(int i=0;i<list2.size();i++) {
            int xvalue= list2.get(i).x; //每一个对应的点的x
            int yvalue= list2.get(i).y; //每一个对应的点的y
            int nums=0;
            //利用曼哈顿公式进行运算 ,并放入mindis数组中。
            for(int j=0;j<list1.size();j++) {
                int num=Math.abs(x[j]-xvalue)+Math.abs(y[j]-yvalue);
                nums+=num;
            }
            mindis[i]=nums;
        }

   5.对mindis数组进行排序,输入第一个值就,因为第一个值就是是最小的距离。

1         Arrays.parallelSort(mindis);
2         System.out.println("最小距离为:"+mindis[0]);

    代码总结:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

class point {
        public int x;
        public int y;
        //构造方法
        public point(int x, int y) {
            this.x = x;
            this.y = y;
        }
}

public  class leetcode296 {
    public static void main(String[] args) {
        //测试数据
        int grid[][]={
                //数据1
//                {1,1}
                //数据2
//                {1,0,1}
                //数据3
//                {1,0,1,0,1}
                //数据4
                {1,0,0,0,1},
                {0,0,0,0,0},
                {0,0,1,0,0}
        };
        System.out.println(minTotalDistance(grid));

    }
    
    public static int minTotalDistance(int[][]grid) {
        // 1.声明两个集合,list1用来存储值为1的点  list2用来存储所有位置的点
        List<point> list1 = new  ArrayList<point>(); 
        List<point> list2 = new  ArrayList<point>();
        //2.遍历数据,将数值放入对应集合  
        for(int i=0;i<grid.length;i++) {
            for(int j=0;j<grid[i].length;j++) {
                list2.add(new point(i,j));  //每个位置放到List2
                if(grid[i][j]==1) {  
                    list1.add(new point(i,j)); //值为1的点放入List1
                }    
            }
        }
        //3.创建两个数组,分别代表每个人的  x位置数组 和y位置数组。并利用list1 集合给数组添加值
        int x[] =new int[list1.size()]; //每个人的x位置
        int y[] =new int[list1.size()];    //每个人都y位置

        for(int i=0;i<x.length;i++) {
            x[i]=list1.get(i).x; //获取list1第i个点的x
            y[i]=list1.get(i).y;//获取list1第i个点的y
        }
        //4.对每个点(list2的点)进行距离运算,并将所有结果放到一个mindis数组中
        int mindis[] = new  int[list2.size()];
        for(int i=0;i<list2.size();i++) {
            int xvalue= list2.get(i).x; //每一个对应的点的x
            int yvalue= list2.get(i).y; //每一个对应的点的y
            int nums=0;
            //利用曼哈顿公式进行运算 ,并放入mindis数组中。
            for(int j=0;j<list1.size();j++) {
                int num=Math.abs(x[j]-xvalue)+Math.abs(y[j]-yvalue);
                nums+=num;
            }
            mindis[i]=nums;
        }
        //5.对mindis数组进行排序,输入第一个值就,因为第一个值就是是最小的距离。
        Arrays.parallelSort(mindis);
        return mindis[0];
    }

}

    结果截图:  

    (侧面反映暴力法真的不太好,本题解仅提供一个解决的思路,并不是最优解!

posted @ 2021-08-02 20:04  木原纺  阅读(347)  评论(0编辑  收藏  举报