子串:原序列中必须连续的一段
子序列:原序列中可以不连续的一段
注意:无论是子串和子序列,元素的顺序都是原序列中的顺序 注意:无论是子串和子序列,元素的顺序都是原序列中的顺序
- 示例1:输入: s = “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
- 示例2:输入: s = “bbbbb” 输出: 1 解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
- 示例3:输入: s = “pwwkew” 输出: 3 解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。 请注意,你的答案必须是子串的长度,”pwke” 是一个子序列,不是子串。
- 示例4:输入: s = “” 输出: 0
提示:0 <= s.length <= 5 * 10^4 s由英文字母、数字、符号和空格组成
public class Test3 {public static void main(String[] args) {String str = "asdf234234fdgbv";System.out.println(lengthOfLongestSubstring(str));System.out.println(lengthOfLongestSubstring2(str));System.out.println(lengthOfLongestSubstring3(str));}/*** 实现方式1:遍历每一个字符串,检查从当前字符串后的字符开始是否跟前面的字符串相同,若相同则不属于子串* 否在属于子串,缺点:使用的是list来保存子串,然后检查是否再list里面时间复杂度要用O(N),所以很慢* 执行用时:1412 ms, 在所有 Java 提交中击败了5.01%的用户 内存消耗:39.4 MB, 在所有 Java 提交中击败了5.08%的用户* @param str* @return*/public static int lengthOfLongestSubstring(String str) {// 用最傻的方法先实现,遍历每个字母开始的最长字串int maxLen = 0;// 定义一个数组来存贮从某一个字符开始的最长子串String maxStr = "";if (str.length() <= 0) {maxLen = 0;} else {List<String> strs = new ArrayList<String>();for (int i = 0; i < str.length(); i++) {// 先获取第一个字符的最长字串// 获取当前要判断的字符char now = str.charAt(i);strs.add(now + "");for (int j = i + 1; j < str.length(); j++) {// 判断跟前面的是否重复char n = str.charAt(j);// 判断n是否在之前的序列里boolean flag = strs.contains(n + "");if (!flag) {System.out.println(n + "属于以" + now + "开头的最长字串");strs.add(n + "");} else {System.out.println(n + "不属于以" + now + "开头的最长字串");break;}}System.out.println("以" + now + "开通要的最长子序列为" + strs.toString());if (strs.size() > maxLen) {maxLen = strs.size();maxStr = strs.toString();}strs.clear();}System.out.println(str + "的最长字串为" + maxStr + "长度为" + maxLen);}return maxLen;}/*** 实现方式2:遍历每一个字符串,检查从当前字符串后的字符开始是否跟前面的字符串相同,若相同则不属于子串* 否在属于子串,改为用map来存放是否在子串中,所以比第一种好一点,但是还是很慢* 执行用时:执行用时:247 ms, 在所有 Java 提交中击败了5.74%的用户内存消耗:39 MB, 在所有 Java 提交中击败了17.15%的用户* @param str* @return*/public static int lengthOfLongestSubstring2(String str) {// 用最傻的方法先实现,遍历每个字母开始的最长字串int maxLen = 0;// 定义一个数组来存贮从某一个字符开始的最长子串Map<String,Boolean> map = new HashMap<String,Boolean>();for (int i = 0; i < str.length(); i++) {// 先获取第一个字符的最长字串// 获取当前要判断的字符char now = str.charAt(i);//这里直接借助map来判断是否存在map.put(now+"", true);int len=1;for (int j = i + 1; j < str.length(); j++) {// 判断跟前面的是否重复char n = str.charAt(j);// 判断n是否在之前的序列里if(map.get(n+"")!=null) {System.out.println(n + "不属于以" + now + "开头的最长字串");break;} else {System.out.println(n + "属于以" + now + "开头的最长字串");map.put(n+"", true);len++;}}if (len > maxLen) {maxLen =len;}System.out.println("以" + now + "开头的字符串maxlen="+maxLen);map.clear();}return maxLen;}/*** 实现方式3:遍历每一个字符串,检查从当前字符串后的字符开始是否跟前面的字符串相同,若相同则不属于子串* 否在属于子串,改为用map来存放是否在子串中,并且如果判断当前字符不属于前一个子串,则字节从前一个冲突的子串的下一位开始判断,这样* 就不用重复判断长度不可能大于当前子串的内容了,比如串“abcdefcg”,我们先判断以a开头的子串,当判断到“abcdefc”的时候,c跟前面的c* 冲突,此时就没有必要判断b和第三个c开头的子串了,直接从d开始即可,节省时间。但还还是不够理想,才7.28%。* 执行用时:164 ms, 在所有 Java 提交中击败了7.28%的用户内存消耗:39 MB, 在所有 Java 提交中击败了16.36%的用户* @param str* @return*/public static int lengthOfLongestSubstring3(String str) {// 用最傻的方法先实现,遍历每个字母开始的最长字串int maxLen = 0;// 定义一个数组来存贮从某一个字符开始的最长子串Map<String,Integer> map = new HashMap<String,Integer>();int now_j=0;for (int i = 0; i < str.length();) {// 先获取第一个字符的最长字串//获取i~now_j之间的字符串String ss = str.substring(i, now_j+1);int len=ss.length();for (int j = 0; j <ss.length(); j++) {map.put(ss.charAt(j)+"", i+j);}//冲突的下标Integer n_index=now_j+1;for (int j = now_j+1; j < str.length(); j++) {// 判断跟前面的是否重复char n = str.charAt(j);// 判断n是否在之前的序列里n_index = map.get(n+"");now_j=j;if(n_index!=null) {//这里表示当前的j和n_index,那下一次循环就可以直接把n_index~j之间的内容break;} else {n_index=j;map.put(n+"", j);len++;}}if (len > maxLen) {maxLen =len;}map.clear();i=n_index+1;}return maxLen;}}
上面是我自己的解题方法,超过的人太少了,丢人!
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays
