百度一道笔试题目的答案

 题目内容为:从字符串s中找出不包含重复字符的最大连续子字符串长度.
public static void main(String[] args) {
     String str = "aaafc";
     List list = new ArrayList();
     int max = 0;
     int len = str.length();
     int c = 0;
     for (int m = 0; m < len; m++) {
          for (int i = c; i < len; i++) {
             if (!list.contains(str.charAt(i))) {//list中不包含则添加对象
                  list.add(str.charAt(i));
            } else {//遇到重复字符时获取该连续字符串长度,并把list清空
                      c++;
                   if (max < list.size()) {
                   max = list.size();
                   }
              list.removeAll(list);
           }
       }
  }
  System.out.println(max);

 }

 

 

以下为引用:

要求实现尽可能高效.
问:是否存在O(n)复杂度的算法

答案(Java语言描述,经过测试):
下面的两个算法,一个是简单算法(利用哈希表),另一个是O(n)复杂度的算法。

 /**
  * 简单算法, 利用 哈希集合 保存遍历过的字符串
  * @param str
  * @return
  */
 static int myFoo(String str){
  int ret = 1;// 如果字符串只有一个字符,返回1
  int startP = 0;// 最长连续不重复字符串的 起始位置
  int endP = 0;// 最长连续不重复字符串的 结束位置
  
  for (int i = 0; i < str.length(); i++) {// 从第i个字符开始寻找
   char c = str.charAt(i);
   HashSet set = new HashSet();
   set.add(""+c);
   for (int j = i+1; j < str.length(); j++) {// 遍历后面的字符串
    // 如果当前字符已经在 哈希集合 中,break
    if ( set.contains(""+str.charAt(j)) ){
     if ( set.size()> ret ){
      ret = set.size();
      startP=i;
      endP = j;
     }
     break;
    } else {
     // 如果没有出现在 哈希集合中,放入 hash集合,继续
     set.add(""+str.charAt(j));
     if (j==str.length()-1){// 遍历到末尾,仍没有出现重复字符
      if ( set.size()> ret ){
       ret = set.size();
       startP=i;
       endP = j+1;
      }
     }
    }
   }
  }
  
//  System.out.println(ret);
  System.out.println("myFoo lstr:"+str.substring(startP,endP));
  return ret;
 }
 
 /**
  * O(n)复杂度的算法
  * 算法思想:保存 字符最后出现的位置, 利用该位置信息计算字符串长度
  * @param str
  * @return
  */
 static int foo( String str ){
  
  int ret = 0; // 将返回的 最长不重复子串长度
  int retStrPos = 0;
  
  int max = 0;// 当前的最长不重复子串长度
  int[] lastPos = new int[26]; // 小写英文字符 最后出现的位置
  Arrays.fill(lastPos, -1);
  
  for (int i = 0; i < str.length(); i++) {
   char c = str.charAt(i);
   
   // 检查是否出现过
   int lastP = lastPos[c-'a'];
   if ( lastP != -1 ){// 出现过
    max = Math.min( max+1, i-lastP);
   } else {
    max++;
   }
   
   if ( max > ret ){// 如果当前长度较大,赋值给 ret
    ret = max;
    retStrPos = i;
   }
   
   lastPos[c-'a'] = i;// 更新最后出现位置 数组
  }
  
  // 输出得到的 最长字符串
//  System.out.println("DEBUG lstr:"+ str.substring(retStrPos-ret+1,retStrPos+1) );
  
  return ret;
 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值