一般要求排序,然后从头尾指针,将复杂度降为O(n);
public static void reverse(int[] v, int N) {
int i = 0;
int j = N - 1;
while (i < j) {
swap(v, i, j); // this is a self-defined function
i++;
j--;
}
}
输入:
s: "abab" p: "ab"
输出:
[0, 1, 2]
解释:
起始索引等于 0 的子串是 "ab", 它是 "ab" 的字母异位词。
起始索引等于 1 的子串是 "ba", 它是 "ab" 的字母异位词。
起始索引等于 2 的子串是 "ab", 它是 "ab" 的字母异位词。
一开始还是先将字符串转换为字符数组,定义一个ans来接收结果
这里使用了两个数组needs和window来分别记录需要得到的元素和滑动窗口遍历到的元素
首先把目标数组arrP中有的元素都放入needs中,然后通过不断移动滑动窗口将目标元素的个数保存到window中
如果window数组中记录的元素个数超过了needs数组的元素个数,则开始移动左窗口慢慢减少多余的个数
最后把整个遍历过程中所有符合要求的左窗口索引放到ans中并返回即可。
class Solution {
public List<Integer> findAnagrams(String s, String p) {
char[] arrS = s.toCharArray();
char[] arrP = p.toCharArray();
// 接收最后返回的结果
List<Integer> ans = new ArrayList<>();
// 定义一个 needs 数组来看 arrP 中包含元素的个数
int[] needs = new int[26];
// 定义一个 window 数组来看滑动窗口中是否有 arrP 中的元素,并记录出现的个数
int[] window = new int[26];
// 先将 arrP 中的元素保存到 needs 数组中
for (int i = 0; i < arrP.length; i++) {
needs[arrP[i] - 'a'] += 1;
}
// 定义滑动窗口的两端
int left = 0;
int right = 0;
// 右窗口开始不断向右移动
while (right < arrS.length) {
int curR = arrS[right] - 'a';
right++;
// 将右窗口当前访问到的元素 curR 个数加 1
window[curR] += 1;
// 当 window 数组中 curR 比 needs 数组中对应元素的个数要多的时候就该移动左窗口指针
while (window[curR] > needs[curR]) {
int curL = arrS[left] - 'a';
left++;
// 将左窗口当前访问到的元素 curL 个数减 1
window[curL] -= 1;
}
// 这里将所有符合要求的左窗口索引放入到了接收结果的 List 中
if (right - left == arrP.length) {
ans.add(left);
}
}
return ans;
}
}
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length();
Set<Character> set = new HashSet<>();
int ans = 0, i = 0, j = 0;
while (i < n && j < n) {
// try to extend the range [i, j]
if (!set.contains(s.charAt(j))){
set.add(s.charAt(j++));
ans = Math.max(ans, j - i);
}
else {
set.remove(s.charAt(i++));
}
}
return ans;
}
}
public class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length(), ans = 0;
int[] index = new int[128]; // current index of character
// try to extend the range [i, j]
for (int j = 0, i = 0; j < n; j++) {
i = Math.max(index[s.charAt(j)], i);
ans = Math.max(ans, j - i + 1);
index[s.charAt(j)] = j + 1;
}
return ans;
}
}
输入: S = "ADOBECODEBANC", T = "ABC"
输出: "BANC"
class Solution {
public static String minWindow(String s, String t) {
if (s == null || s == "" || t == null || t == "" || s.length() < t.length()) {
return "";
}
//用来统计t中每个字符出现次数
int[] needs = new int[128];
//用来统计滑动窗口中每个字符出现次数
int[] window = new int[128];
for (int i = 0; i < t.length(); i++) {
needs[t.charAt(i)]++;
}
int left = 0;
int right = 0;
String res = "";
//目前有多少个字符
int count = 0;
//用来记录最短需要多少个字符。
int minLength = s.length() + 1;
while (right < s.length()) {
char ch = s.charAt(right);
window[ch]++;
if (needs[ch] > 0 && needs[ch] >= window[ch]) {
count++;
}
//移动到不满足条件为止
while (count == t.length()) {
ch = s.charAt(left);
if (needs[ch] > 0 && needs[ch] >= window[ch]) {
count--;
}
if (right - left + 1 < minLength) {
minLength = right - left + 1;
res = s.substring(left, right + 1);
}
window[ch]--;
left++;
}
right++;
}
return res;
}
}
s: "cbaebabacd" p: "abc" 输出: [0, 6]
class Solution {
public List<Integer> findAnagrams(String s, String p) {
int []needle=new int[26];
int[]windows=new int[26];
List<Integer> ans = new ArrayList<>();
char[]p1=p.toCharArray();
char[]s1=s.toCharArray();
for(char p2:p1){
needle[p2-'a']+=1;
}
int left=0;
int right=0;
while(right<s.length()){
int curRight=s1[right]-'a';
windows[s1[right]-'a']+=1;
right++;
while(windows[curRight]>needle[curRight]){
windows[s1[left]-'a']-=1;
left++;
}
if (right - left == p1.length) {
ans.add(left);
}
}
return ans;
}
}
输入: s = 7, nums = [2,3,1,2,4,3]
输出: 2
解释: 子数组 [4,3] 是该条件下的长度最小的连续子数组。
class Solution {
public int minSubArrayLen(int s, int[] nums) {
int i = 0;
int sum = 0;
int len = 0;
for (int j = 0; j < nums.length; j++) {
sum += nums[j];
while (sum >= s) {
len = len == 0 ? j - i + 1 : Math.min(len, j - i + 1);
sum -= nums[i++];
}
}
return len;
}
}
public class StringUtils {
/**
* @param originalStr the string we want to append to with spaces
* @param size the target length of the string
* @return a string
*/
static public String leftPad(String originalStr, int size) {
// Write your code here
return leftPad(originalStr, size, ' ');
}
/**
* @param originalStr the string we want to append to
* @param size the target length of the string
* @param padChar the character to pad to the left side of the string
* @return a string
*/
static public String leftPad(String originalStr, int size, char padChar) {
// Write your code here
StringBuffer sb = new StringBuffer();
for (int i = 0; i < size - originalStr.length(); ++i)
sb.append(padChar);
sb.append(originalStr);
return sb.toString();
}
}
[
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
Given target = 3, return true.从左到右递增;行末尾小于第二行的开头;
难点是坐标的转换;
public class Solution {
/**
* @param matrix, a list of lists of integers
* @param target, an integer
* @return a boolean, indicate whether matrix contains target
*/
public boolean searchMatrix(int[][] matrix, int target) {
// write your code here
if(matrix == null || matrix.length == 0){
return false;
}
if(matrix[0] == null || matrix[0].length == 0){
return false;
}
int row = matrix.length;
int column = matrix[0].length;
int start = 0, end = row * column - 1;
while(start <= end){
int mid = start + (end - start) / 2;
int number = matrix[mid / column][mid % column];
if(number == target){
return true;
}else if(number > target){
end = mid - 1;
}else{
start = mid + 1;
}
}
return false;
}
}