博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
给定一个字符串,找出不含有重复字符的最长子串的长度。
阅读量:6644 次
发布时间:2019-06-25

本文共 3690 字,大约阅读时间需要 12 分钟。

題目描述:

  给定一个字符串,找出不含有重复字符的最长子串的长度。

思路1:

  依排列组合的所有可能拿到所有子串,依次传入重复子穿的判断方法中进行判断,每次更新出不重复子串的最大长度!

具体代码:

 

1 import java.util.Scanner; 2  3 public class test{ 4     public static void main(String[] args) { 5         Scanner sc = new Scanner(System.in); 6         System.out.println("请输入一列字符串:"); 7         String line = sc.nextLine(); 8         System.out.println("该字符串的最长五重复子穿的长度是:" + test.lengthOfLongestSubstring(line)); 9     }10 11     public static int lengthOfLongestSubstring(String s) {12         StringBuffer sb = new StringBuffer(s); // 转为StringBuffer调用更多的字符串方法13         int length = 0; // 无重复子串最大长度的表示14         for (int i = 0; i < sb.length(); i++) {15             for (int j = i + 2; j < sb.length() + 1; j++) {16                 if (!IsChongFu(sb.substring(i, j))) { // 按所有排列组合的可能截取出所有子串,传入判断函数17                     if (sb.substring(i, j).length() > length) {18                         length = sb.substring(i, j).length(); // 更新待返回的长度19                     }20                 }21             }22         }23         return length;24     }25 26     private static boolean IsChongFu(String obj) {
// 判断子串是否重复27 for (int k = 0; k < obj.length() - 1; k++) {28 for (int l = k + 1; k < obj.length(); l++) {29 if (obj.charAt(k) == obj.charAt(l)) {30 return true;31 }32 }33 }34 return false;35 }36 37 }

 

一点思考:

  上述算法的时间复杂度似乎不太理想,返回长度的方法以及判断重复的方法都用到了两层for循环,能否改进一下呢???

我是这样想的:

  遍历字符串,用一个数据容器来依次接收遍历到的每一个字符,当即将接收容器里已经出现的字符时,用lengh存储容器此时元素的实际个数,即长度,并删除容器内重复位置及之前的所有元素;然后继续接收字符,如果又遇到重复,执行上述操作,比较并更新出最大长度;直到字符串遍历结束,再次更新出最大长度。

  因此,我利用Set集合不存储重复元素的特性,选用Set中存取一致的LingkedHashSet来当作算法所需的容器。

具体代码:

 

1 import java.util.LinkedHashSet; 2 import java.util.Scanner; 3  4 public class test再改进 { 5  6     public static void main(String[] args) { 7         System.out.println("请输入一列字符串:"); 8         Scanner sc = new Scanner(System.in); 9         String line = sc.nextLine();10         System.out.println("该字符串的最大无重复子串的长度为:" + findLargestOfLine(line));11     }12 13     private static int findLargestOfLine(String line) {14         // 创建容器15         LinkedHashSet
set = new LinkedHashSet<>();16 // 遍历字符串,并存入容器17 int largest = 0;18 for (int i = 0; i < line.length(); i++) {19 if (!set.add(line.charAt(i))) { // 此操作先执行存储,若成功存储则不进行其余操作:若不能存储,则表示该元素是重复元素20 largest = set.size() > largest ? set.size() : largest;// 更新并记录容器内的长度21 // 删除重复位置及之前的元素22 // for (Character c : set) {23 // if(c==line.charAt(i)) {24 // set.remove(c);25 // continue;26 // }else //标注的代码目的也是想实现删除操作,但暴露出的问题是:Set集合中不能在遍历的同时进行删除操作,否则否抛出异常27 // set.remove(c);28 // }29 LinkedHashSet delSet = new LinkedHashSet<>();// 解决上述问题的办法是将要删除的元素存入集合,遍历完成再删除30 for (Character c : set) {31 delSet.add(c);32 if (c == line.charAt(i))33 break;34 }35 set.removeAll(delSet);// 先删除36 set.add(line.charAt(i));// 再将遇到的重复元素添加到set中37 }38 // 每一次遍历都实现了set中重复位置及之前的删除,重复元素的添加,最大长度的更新39 }40 // 当字符串遍历完成,还要执行依次最大长度的更新41 largest = set.size() > largest ? set.size() : largest;42 43 return largest;44 }45 46 }

总结:

第一种思路及算法很蛮力,for嵌套用得多,第二种思路及方法显得就要轻松多了!!!

蛮力法主要包含:

  1.String转StringBuffer后可使用的截取功能(SubString());

  2.字符串是否出现重复的判断算法

另一种方法主要包含:

  1.LingkedHashSet存储无重复元素,且存取一致;

  2.Set集合不能边遍历边删除

转载于:https://www.cnblogs.com/zclun/p/9962438.html

你可能感兴趣的文章
element-ui 版本升级对比
查看>>
js 整理
查看>>
Java Socket基础(二)
查看>>
Xamarin XAML语言教程Xamarin.Forms中改变活动指示器颜色
查看>>
Jenkins Master/Slave架构
查看>>
Linux Shell 程序调试
查看>>
Oracle Dimension
查看>>
使用客户端登陆ftp 500 OOPS: cannot change directory:/root
查看>>
docker 私用仓库Harbor搭建及配置
查看>>
理解HTTP协议
查看>>
巧用分类信息做网站的口碑推广
查看>>
理解并取证:ICMPV6代替IPV4中的ARP进行IPv6的MAC地址解析
查看>>
数据库知识体系梳理(一)
查看>>
我的友情链接
查看>>
一个很酷的加载loading效果
查看>>
Java解析json串
查看>>
光照模型与面绘制算法---OpenGL光照和表面绘制函数
查看>>
系统文件的损坏导致Windows XP连续重启的解决方案
查看>>
北京点击科技有限公司董事长兼总裁——王志东经典语录5
查看>>
Linux误删home目录下的用户目录恢复
查看>>