LeetCode java Longest Substring Without Repeating Characters

一. 题目:

   Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3. For "bbbbb" the longest substring is "b", with the length of 1.

二. 首先学习java知识点:

  1. HashMap / HashTable:

   Hashtable与HashMap相同的一点:无序存放。

  2. java中的String类型:    参考:好复杂,基础知识薄弱,呜呜。。。。http://www.360doc.com/content/14/1107/23/17130779_423471141.shtml

     C语言中没有String字符串这个类型,有字符数组;智能用字符数组的一种特殊形式表示字符串,即该字符数组的最后一个元素必须以‘\0(空)’来结尾。

           例如: char  c[] = "abcd" 是一个字符串,他的长度是5,char[4] ='\0';

                        char c[6] ="asdfg"也是字符串,

                       但char c[5]="asdfg"只是一个字符数组,因为它最后一个元素不是'\0',如果对字符数组c执行string.h里面的函数的时候,就会报错。

     当然,用C语言实现一个字符串容器不难,java是从C语言发展来的,实现了该容器为String类。

    (感觉自己可不求甚解了,人家这么精彩的博客我看了一丢丢就木有耐心看了,这样子是不是什么都做不好,亲你该转行了可怜 等下次用到的时候在看吧,先把这个第三题做出来再说尴尬

  3. java遍历String类型的数组

      String str = "12345678qwertyu";
        for (int i = 0; i < str.length(); i++) {
            char  item =  str.charAt(i);
            System.out.println(item);

4.长度获得

       数组 s.length           字符串 s.length()                list ~ list.size();             map~ map.size();                set  ~set.size();



三  .利用java String完成

      你绝壁没见过如此白痴的代码。。执行后,状态是: 

      Submission Result: Time Limit Exceeded
public class Solution {
    public int lengthOfLongestSubstring(String s) {
        if(s== null)   //所有可能出现的问题都应该考虑在内
          return 0;
      //  Map map1 = new HashMap();
      //  Map map2 = new hashMap();  //突然觉得搞两个String类型的指针就行  我是不是啥,为啥要搞两个,当出现重复的时候直接记录下长度然后清空就好啊
      //  String A  //由于插入字符,已经比较没有用HashMap方便,所以不采用String类型   
      //定义两个字符串进行存储s里面的子字符串,并进行长度的比较
      //string A;                         //明知道我这中定义方法是错的。。居然还是像C语言中一样,这样傻傻的定义变量
      String A = new String();
      String B = new String();    
      int length = 0;
        
        //遍历整个字符串
        for(int i=0; i<s.length(); i++){
            char  item =  s.charAt(i); 
       //     if(! map1.containskey(item)){    
        //        map1                        //但是突然考虑到一个问题,如果只是简单的获得这个子字符串的长度的话,用HashMap就够了,
                                            //但还要知道具体的子字符串,因为hashMap是无序存放。  所以还是用字符串表示比较好么.
            if(A==null || A.indexOf(item)!= -1){    //表示不存在该字符,则把该字符加入到A中
                A+=item;
                length = A.length();
            } else{
                if(B==null || B.indexOf(item)!=-1){
                    B+=item;
                    length = length > B.length()?length:B.length();
                }else{     //即A中也有,B中也有,那么就先比较A和B的大小,然后把小的那个清零,在继续想其中添加字符
                    if(A.length() > B.length()){
                        B = null;
                        B+=item;
                    }else{
                        A = null;
                        B+=item;
                    }
                }
            }
        }
       return length;    //傻了吧,到最后才发现人家要返回的是长度,没有要返回子字符串好么。。折腾的用String类。
       
    }
}

上面的思路有问题。。。。算是记录下自己的错误吧。。


四。利用HashMap完成题目

 参考连接:  http://www.programcreek.com/2013/02/leetcode-longest-substring-without-repeating-characters-java/

  java知识点学习:

    1) String.toCharArray()     把字符串转化成字符串数组    把字符串转化成字符串数组,那么对应每个字符串都没有必要比较字幕,char类型就256个,直接和这些个比较就好。

     2) Math.max(  ,   )  相当于  A > B ? A : B;     java.lang.Math.max(int a, int b) 一般为int型

下面的思路没问题,但是时间复杂度太高。  the time complexity is higher - O(n^3).

Submission Result: Time Limit Exceeded
public class Solution {
    public int lengthOfLongestSubstring(String s) {
        if(s== null)   //所有可能出现的问题都应该考虑在内
          return 0;
     
     int length = 0;
     char[] c = s.toCharArray();
     HashMap<Character , Integer> map = new HashMap<Character , Integer>();
     for(int i=0; i<c.length; i++){   //之前自己写的是String类型,所以用s.length();
        if(! map.containsKey(c[i])){
            map.put(c[i],i);
        }else{       
            length = Math.max(length,map.size());  //map里面已经存在了,则记录下之前所有的最长的子字符串的长度,然后继续循环操作
            i = map.get(c[i]);  //呜呜,看到这句话我才理解我之前的理解一直是错了的  例如:abcadeaed  当第二次遇到a的时候,
                                //不应该吧前面全部抛弃,只需要把那个重复的a抛弃掉就好啊。。。这才真正理解题意,我真的是猪。
            map.clear(); 
        }
     }
     return Math.max(length, map.size());
    }
}


五. 用StringBuffer实现    (来自凑凑的帮助)

 

str = str.substring(int x)   去掉从首位开始的长度为x的字符串,剩下的赋值给str.

    String s1 ="1234567890abcdefgh";
     s1 = s1.substring(10);
    System.out.println(s1);                    运行结果:abcdefgh

str=str.substring(int beginIndex,int endIndex);截取str中从beginIndex开始至endIndex结束时的字符串,并将其赋值给str;

  String s1 ="1234567890abcdefgh";
  s1 = s1.substring(0,9);
  System.out.println(s1);           运行结果:123456789
 

Submission Result: Time Limit Exceeded

public static int lent(String s){
		
		StringBuffer buffer = new StringBuffer();
		int k =0 ;
		int i =0 ;
		//字符窜的长度进行循环
		for(int j = 0 ; j < s.length() ;j++){
		String subString = s.substring(j);
		buffer.delete(0, buffer.length());
		for (i = 0 ; i < subString.length(); i++) {
				// 该次循环的字符(字符窜表示了)
				String singleString = subString.substring(i, i + 1);
				// if语句判断,如果循环过的字符窜不包含该次的字符,则把字符加到字符窜
				if (!(buffer.toString().contains(singleString))) {
					buffer.append(singleString);
					// 如果循环过的字符窜包含该次的字符,跳出循环,程序结束
				} else {
					break;
				}
			}
		if( k < i){
			k = i;
		}
		}
		return k;
	}



六. 参考网上的博客学习代码    学习链接: http://my.oschina.net/jdflyfly/blog/283405

Runtime: 396 ms

public class Solution {
    public int lengthOfLongestSubstring(String s) {
     if(s==null || s.length() < 1){
         return 0;
     }
     int res = 1;  //接下来的长度肯定是大于0的,所以i这里从1开始
     boolean[] exit = new boolean[256];   //用来存放已经存在的字符,如果存在就标识为true,否则为false
     int start = 0; //用来跟新res的长度使用
     
     for(int i=0; i<s.length();i++){
          char ch=s.charAt(i);
          if(exit[ch]){   //证明开始有重复了,此时不确定重复了前边遍历过得字符串的那字符,则重新开始给start赋值,并计算res的长度
             res = Math.max(res,i-start);
             for(int k=start; k<i; k++){
                 if(s.charAt(k)==ch){
                     start = k +1;
                     break;
                 }else{
                     exit[s.charAt(k)]=false;
                 }
             }
              
          }else{
              exit[ch]=true;
          }
     }
      res = Math.max(res,s.length()-start);//最后遍历的那个字符串和之前的res进行比较
      return res;

    }
}


 




  

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值