这是我遇到的一道校招题目:
给定一字符串只包含数字,请写一个算法,找出该字符串中的最长不重复子串(不重复是指子串中每一元素不同于子串中其他元素)
如: “120135435”最长不重复子串为 "201354"
要求用java或者c来写,我用了java。
/**
* 思想:
* 从头开始截取字符串,只要后一个元素不在截取的字符串里,就更新截取,多截取一个元素。
* 如果发现后一个元素出现在字符串里, 将最后截取的字符串存为临时结果,开始位置后移一位,结束位置为开始位置下一位....
*
* 从靠前那个发生重复的字符后一位 开始 向 刚刚截取到的结束为止后一个字符 一个一个向后截取字符串....
* 如果新一轮截取的字符串比临时结果长,就更新临时结果
* 从头到尾所有部分都尝试截取之后,返回最长的那个临时结果
*
* 伪代码:
* 用start 和end 标记我截取的字符串的开始和结束的位置。 刚开始 start = 0 end = 1
* 循环:start从0到 待截取字符串的倒数第二个元素
* 0 结果字符串res ,初始为空字符串“”
* 1 从start 到end之前一个元素 把 str 截取一个临时字符串 temp
* 2 循环:
* 判断end所在字符是否在temp里面出现过
* 否: end++ 更新temp赋值成新的 从start 到end前一个元素的字符串
* 是: 跳出循环
* 3 在2循环中 temp 不断被更新, 跳出2循环后,如果temp比res长,就更新res为temp,否则什么都不做
* 4 start后移一位 , end改为start的下一位
*
*/
我的代码:
1 class Solution{ 2 public String find_longest_sub( String str ){ 3 String res = ""; //用于存找到的子序列 4 int start = 0; // 查找子串的开始位置 5 int end = 1; // 子串的结尾位置 6 7 while(start < str.length()-1 && end < str.length() ){ //开始位置还没到str的倒数第二个字符 就一直循环 8 /** 9 * 只要后一个元素不在之前截取的字符串里,end后移一位,更新字符串截取 10 */ 11 String temp = str.substring(start, end); // 截取一个临时字符串 从start到end前一位 12 while( end < str.length() && temp.indexOf( str.charAt(end) ) == -1 ){ 13 end++; 14 temp = str.substring(start, end); 15 } 16 // 跳出循环说明下一个元素与当前截取字符串重复了 17 18 //如果当前截取比临时结果长 就更新临时结果 再重新开启一轮查找位置 19 if(temp.length() > res.length()){ 20 res = temp; 21 } 22 23 // 将新的起始位置自增1 end调整到start的下一位 24 start++; 25 end = start +1; 26 27 } 28 29 return res; 30 } 31 32 }