题目:
给定一个二进制数组, 找到含有相同数量的 0 和 1 的最长连续子数组(的长度)。
分析:
我首先看到这个题目的时候想到的是可不可以用动态规划求解,后来发现由于他中间数字的变化并没有规律,你可以得到当前位置0和1的差值,但是无法规律得找到最远相同差值的位置,所以最后我失败了。
然后我用了第二种方法
代码:
1 //HashMap 98ms 26% 2 class Solution525 { 3 public int findMaxLength(int[] nums) { 4 if(nums.length<2) 5 return 0; 6 HashMap<Integer, Integer> hm=new HashMap(); 7 int max=0; 8 int[] count=new int[nums.length]; 9 if(nums[0]==0) 10 count[0]=-1; 11 else 12 count[0]=1; 13 hm.put(count[0], 0); 14 for(int n=1;n<nums.length;++n) { 15 if(nums[n]==0) 16 count[n]=count[n-1]-1; 17 else 18 count[n]=count[n-1]+1; 19 if(count[n]==0) 20 max=max>(n+1)?max:(n+1); 21 else{ 22 if(!hm.containsKey(count[n])) 23 hm.put(count[n], n); 24 max=max>(n-hm.get(count[n]))?max:(n-hm.get(count[n])); 25 } 26 System.out.println("第"+n+"位:"+count[n]); 27 } 28 return max; 29 } 30 }
这个方法运算速度并不快,但是我可以将第一个出现的新的差值保存,然后当后续出现相同的差值,就从hm中找到他的位置,求出最大值。
下面是最快的方法
代码:
1 //20ms 100% 新开辟空间较大 2 class Solution525 { 3 public int findMaxLength(int[] nums) { 4 if(nums.length<2) 5 return 0; 6 int max=0; 7 int len=nums.length; 8 int[] count=new int[len]; 9 int[] sto=new int[2*len+1]; 10 for(int n=0;n<2*len+1;++n) 11 sto[n]=Integer.MAX_VALUE; 12 if(nums[0]==0) 13 count[0]=-1; 14 else 15 count[0]=1; 16 sto[len+count[0]]=0; 17 for(int n=1;n<len;++n) { 18 if(nums[n]==0) 19 count[n]=count[n-1]-1; 20 else 21 count[n]=count[n-1]+1; 22 if(count[n]==0) 23 max=max>(n+1)?max:(n+1); 24 else{ 25 if(n<sto[len+count[n]]) 26 sto[len+count[n]]=n; 27 max=max>(n-sto[len+count[n]])?max:(n-sto[len+count[n]]); 28 } 29 System.out.println("第"+n+"位:"+count[n]); 30 } 31 return max; 32 } 33 }
这段代码执行速度很快,我创建了够长的数组,可以免去繁琐的查询步骤,但是相对的就要开辟很大的空间。
这样做有一定的问题,也就是当nums数组太长时,创建的sto数组可能会无法创建。