题目:(根据回忆写的,只描述了大概意思)
现有一组0、1字符串,其字符数为m,可以将0更改为1的最大次数为n。在字符串中肯定存在在改动n次以内的最长的只由1组成的子串。最长子串可能会出现多次,现在求最长子串出现的次数。
其中,如果1的位置不发生变化就认为是一次。例如:对3,2, “010”来讲,先改第一个0后改第二个0的结果都是“111”,只算做最长子串出现一次。
例子:
样例:5,2,"10101"
样例结果:1
样例代码:
1 package test4ljd; 2 3 import javax.swing.plaf.basic.BasicInternalFrameTitlePane.MaximizeAction; 4 5 public class test4ljd { 6 public static void main(String[] args){ 7 //System.out.println("------------"+ maxZi(7,1,"1010101")); 8 System.out.println("------------"+ maxZi(5,2,"10101")); 9 10 } 11 12 public static int maxZi(int m, int n, String s){ 13 int countf = 0; 14 //代码内容 15 16 return countf; 17 } 18 }
这个问题看着就头疼,感觉像是动态规划,自己实在是不喜欢动态规划的问题,所以就用枚举的方式暴力解决了。
解决的方式就是,因为我们不知道经过n次以内将0改为1的最长连续1子串为多大。所以
我们就先假设其最长连续1子串为字符串的长度,然后比对得到需要将0修改几次,如果修改次数在允许范围之内那么就说明此子串为最大子串,即种类数为1个;
如果最长连续1子串的长度不是字符串长度,接着假设最长连续1子串为字符串长度减1,然后依次和长度为字符串长度减2的子串对比,得到需要修改0的次数,如果修改次数在允许范围内,那么就说明最大子串为此子串,种类个数需要在比对的过程中计数,如果最长子串不是此子串,那么继续;
假设最长1子串的长度位字符串长度减2,然后依次比对,得到修改0的次数,.............
很笨的解决方案,甚至在很长的时候,会浪费大部分的时间和空间在程序中,如果字符串长度很长的情况下。
仓促间写的代码如下:
1 package test4ljd; 2 3 import javax.swing.plaf.basic.BasicInternalFrameTitlePane.MaximizeAction; 4 5 public class test4ljd { 6 7 public static void main(String[] args){ 8 9 //System.out.println("------------"+ maxZi(7,1,"1010101")); 10 System.out.println("------------"+ maxZi(5,2,"10101")); 11 12 } 13 14 public static int maxZi(int m, int n, String s){ 15 int countf = 0; 16 17 int[] a = new int[m]; 18 for (int i = 0; i < a.length; i++) { 19 a[i]=Integer.valueOf(s.charAt(i)-48); 20 if (a[i]==1) { 21 a[i] = -1; 22 } 23 } 24 25 //寻找最大子串 26 for (int i = m; i > 0; i--) { 27 //设最大子串为b 28 int[] b = new int[i]; 29 int[] f = new int[i]; 30 for (int j = 0; j < b.length; j++) { 31 b[j] = 1; 32 } 33 //遍历看最小改变次数多少 34 countf = 0; 35 boolean countg = false; 36 int count = 0; 37 int l = m-i; 38 for(int j = 0; j <= l;j++){ 39 System.arraycopy(a, j, f, 0, i); 40 //两个数组对应位置相加,并求和 41 count = 0; 42 for (int k = 0; k < b.length; k++) { 43 count += (b[k] + f[k]); 44 if (count > n) { 45 break; 46 } 47 } 48 if (count <= n) {//寻找到最大子串 49 countg = true; 50 countf+=1; 51 } 52 } 53 if (countg) {//寻找到最大子串,并保留countf,此时countf是方法数 54 break; 55 } 56 } 57 58 return countf; 59 } 60 }