欢迎使用CSDN-markdown编辑器

来源:互联网 发布:淘宝职业打假起诉法院 编辑:程序博客网 时间:2024/05/20 11:20

从零单排Leetcode

Q3: Longest Substring Without Repeating Characters

1. Brute Force

class Solution {    public int lengthOfLongestSubstring(String s) {        int res = 0;        for(int i=0; i<s.length(); i++){            for(int j=i; j<s.length(); j++){                if(WithoutRepeating(i, j, s)){                    res = Math.max(res, j-i+1);                    }            }        }        return res;    }        public boolean WithoutRepeating(int start, int end, String s){    //检测String是否包含相同character            Set<Character> hs = new HashSet<>();            for(int i=start; i<=end; i++){                                                 if(hs.contains(s.charAt(i))){                    return false;}                hs.add(s.charAt(i));            }            return true;        }}

注意点:
1. 注意如何写一个检测字符串是否包含重复字符的方法。利用java中的HashSet数据结构,查找时间复杂度均为O(1)。同时注意该方法在一次循环中同时进行重复值的查找和元素的添加,而不是先将所有元素加入HashSet中再查找,这样可以将时间复杂度由O(2n)降为O(n)。
2. HashSet中Set接口的一个实现类,本质是Set,即无顺序的存储数据。内部运算机制与HashMap相同,只不过HashMap需要键值对,而HashSet只需要键,而把相应的值自动设定为Object。
3. HashSet添加元素使用的.add()方法,与HashMap的.put()方法不同。
4. 在返回最大值的时候用 res = Math.max(res, 表达式);
5. 计算字符串长度的方法是s.length()。注意带后面的括号,而数组nums.length不带括号。
6. 读取字符串中的第n个元素使用方法s.charAt(n)。

2. Sliding Window

class Solution {    public int lengthOfLongestSubstring(String s) {        Set<Character> hs = new HashSet<>();        int res = 0;        int i = 0,j = 0;        while(j<s.length()){            if(!hs.contains(s.charAt(j))){                hs.add(s.charAt(j++));                res=Math.max(res, j-i);            }            else{                hs.remove(s.charAt(i++));            }        }        return res;    }}

注意点:
1. 采用字符串处理中常用的Sliding Window方法完成。A window is a range of elements in the array/string which usually defined by the start and end indices, i.e. [i, j)[i,j) (left-closed, right-open). A sliding window is a window “slides” its two boundaries to the certain direction.在这里比较tricky的地方是,如果在右边界滑动的过程中发现了当前HashSet中包含了重复元素,那么从左边界开始移动直到消除重复为止。
2. 在时间复杂度的计算上,最坏情况是i,j分别遍历了整个字符串,即O(2n)。
3. HashSet中去除某个元素的方法是.remove()。
4. res=Math.max(res, j-i); 这句话在计算长度的时候不是 j-i+1,原因是上面的语句调用了j++,即j已经加过1了。

3. Sliding Window Opitmized

class Solution {    public int lengthOfLongestSubstring(String s) {        Map<Character,Integer> map = new HashMap<>();        int res = 0;        for(int i=0, j=0; j<s.length(); j++){            if(map.containsKey(s.charAt(j))){                i = Math.max(map.get(s.charAt(j))+1,i);            }            map.put(s.charAt(j), j);            res = Math.max(res, j-i+1);        }        return res;    }}

注意点:
1. 这里用HashMap代替HashSet,目的是更快速的返回i的合适位置。The reason is that if s[j] have a duplicate in the range [i, j) with index j’​​, we don’t need to increase i little by little. We can skip all the elements in the range [i,j​′) and let i to be j’+1 directly.

原创粉丝点击