• 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];
        }
    
    }

        结果截图:  

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

  • 相关阅读:
    IT名词备忘录——汇编
    逆转链表的实现
    编写安全的代码的一些技巧
    extern c 谈
    回调函数
    职场必备八个黄金句型
    CString类的用法介绍和自己动手写的CString类
    61条面向对象设计的经验原则(转贴)
    sprintf的用法
    VisualStudioVS2010统计代码行数
  • 原文地址:https://www.cnblogs.com/songchengyu/p/15091107.html
Copyright © 2020-2023  润新知