标签:leetcode java findsubstring
题目链接:
https://leetcode.com/problems/substring-with-concatenation-of-all-words/
参考链接:
http://www.w2bc.com/Article/14500
思路:
题目大意为,给定一个字符串S和一个字符串数组L,L中的各字符串长度均相等。找出S中所有的子串,这些子串恰好包含L中所有字符各一次,返回子串启始位置。
解题步骤:
1.用map表示L,map中的Key为L中的各字符串,Value为该字符串出现次数
2.执行循环,用str表示S中的各字符串,cnt表示S中包含的L中字符串的个数。若map中key包含str且对应的value大于0(因为要恰好包含1次,),则cnt++,map中str对应的value--。若cnt==
L.length,则这一段满足题目要求。接着再次初始化map,继续执行循环
3.返回结果集
code:
package alivebao; import java.util.ArrayList; import java.util.HashMap; import java.util.List; /** * You are given a string, S, and a list of words, L, that are all of the same * length. Find all starting indices of substring(s) in S that is a * concatenation of each word in L exactly once and without any intervening * characters. * * For example, given: S: "barfoothefoobarman" L: ["foo", "bar"] * * You should return the indices: [0,9]. (order does not matter). * * @author Administrator * */ public class Solution { public static List<Integer> findSubstring(String S, String[] L) { List<Integer> ans = new ArrayList<Integer>(); if (S.length() < 1 || L.length < 1) return ans; int len = L[0].length(); // 题目说L中每个单词长度一样 // 初始化HashMap,注意L中可能包含多个相同的字符串,所以用value表示个数 HashMap<String, Integer> map = new HashMap<String, Integer>(); for (int j = 0; j < L.length; j++) { if (map.containsKey(L[j])) { map.put(L[j], map.get(L[j]) + 1); } else { map.put(L[j], 1); } } // i的范围很关键,如果直接到S.length()是会超时的 for (int i = 0; i <= S.length() - L.length * len; i++) { int from = i; String str = S.substring(from, from + len); int cnt = 0; while (map.containsKey(str) && map.get(str) > 0) { map.put(str, map.get(str) - 1); cnt++; from += len; if (from + len > S.length()) break; // 注意越界 str = S.substring(from, from + len); } // L中每个单词恰好出现一次,加入到结果集 if (cnt == L.length) { ans.add(i); } // 为下一次初始化HashMap if (cnt > 0) { map.clear(); for (int j = 0; j < L.length; j++) { if (map.containsKey(L[j])) { map.put(L[j], map.get(L[j]) + 1); } else { map.put(L[j], 1); } } } } return ans; } public static void main(String[] args) { // TODO Auto-generated method stub String s = "barfoothefoobarman"; String[] L = { "foo", "bar" }; List<Integer> a = new ArrayList<Integer>(); a = findSubstring(s, L); for (Integer t : a) { System.out.println(t); } } }
Longest Substring Without Repeating Characters的大致要求即为求出最长的不重复子串。解法:
Longest Substring Without Repeating Characters
package alivebao; /** * 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. * * @author Administrator * */ public class Solution { public static int lengthOfLongestSubstring(String s) { int maxLen = 0; if (s == null || s.length() == 0) return 0; HashSet<Character> set = new HashSet<Character>(); int walker = 0; int runner = 0; while (runner < s.length()) { if (set.contains(s.charAt(runner))) { if (maxLen < runner - walker) maxLen = runner - walker; while (s.charAt(walker) != s.charAt(runner)) { set.remove(s.charAt(walker)); walker++; } walker++; } else set.add(s.charAt(runner)); ++runner; } maxLen = Math.max(maxLen, runner - walker); return maxLen; } public static void main(String[] args) { // TODO Auto-generated method stub System.out.println(lengthOfLongestSubstring("ababc")); } }
解决思路:
用两个下标walker和runner组成一个不包含重复字符的窗口,runner每次向右移一个字符,若该字符与窗口中的各字符不重复,则继续右移。若重复,则walker移至与runner位置指向的字符相同的字符位置之后一位(比如说walker与runner组成的窗口中第三个字符与runner此时指向的字符相同,则将walker移动至窗口的第四个字符的位置),建立一个新窗口,继续循环
把这题的思路应用于本题,可求出字符串S中,以L[0].length为单位的各不重复子串,然后判断是否包含L。
LeetCode-Substring with Concatenation of All Words
标签:leetcode java findsubstring
原文地址:http://blog.csdn.net/miaoyunzexiaobao/article/details/44802731