Longest Substring Without Repeating Characters Total
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.
这是Leetcode的算法第三题,题目大概意思是给你一个字符串,你要从中找出最长的,没有重复的子串。
我对于这一题的最初思路是运用动态规划的思想,设计出一个窗口,这个窗口中包含的字符串是无重复的,然后这个窗口一直移动,直到最后一个字符,在这个过程中就找到了最长无重复子串。
具体实现是用i记录窗口的左端点,j记录窗口的右端点,如果j节点的字符与前面的字符不重复,则j右移,扩大窗口。如果j节点的字符与前面的字符重复,则i右移到与j节点的相同字符节点的下一个节点,窗口左端右移。
在这个过程中,用max来记录子串的长度,每一次j变化的时候,比较j-i与max的大小,把大的值赋给max。
但在实现这个思路的时候,遇到了一个问题:我还是太傻太天真,没有找到好的办法确定j节点的字符与前面的字符是否重复。百思不得其解,遍历嘛,太慢,而是实现复杂,于是弄了很久没有解决,就查看了一下结题思路。
然后,麻辣,真是日了狗,这也能用hashmap!!!这真是不要脸了,这算不算开挂,竟然是用haspmap把字符作为key,字符的下标作为value,然后,key值重复的时候,put会返回原key关联值,不重复则返回null,这就轻松判断了,我感受到了世界的恶意。
好吧,确实是我少见多怪,再查一下,才知道动态规划+hashmap是解决最什么子串啦,之类问题的非常优秀的通解。我想静静。
代码如下
public static int lengthOfLongestSubstring(String s) {
int i = 0;
int j = 0;
int max = 0;
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
// 当右端点到达字符串最后是结束循环
while (j<s.length()) {
Object k = map.put(s.charAt(j), j);
// 如果有重复字符串,左端点移动到重复字符的下一个节点位置
if (k != null) {
// 处理特殊情况,若后面字符跟已经跳过的前面字符重复,拒绝回溯
if (i<(Integer)k+1) {
i = (Integer)k+1;
}
map.put(s.charAt(i), i);
}
j++;
// 如果新的子串比前面的最长子串还要长,交换长度
if (j - i > max) {
max = j - i;
}
}
return max;
}
怎么办!还是要提交好多次,看看case才会改程序,自己想的根本没有那么全面!怎么办,怎么才能一次ac?!