一、无重复字符的最长子串
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
(请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。)
//思路:用双指针,遇到重复的,左指针就到重复的下标处
class Solution {
public int lengthOfLongestSubstring(String s) {
int left=0;
int right=0;
int max=0;
char[] windows = new char[128];
for(right=0;right<s.length();right++){
char ch = s.charAt(right);
windows[ch]++;
//有重复字符,左指针移动到重复字符处
while(windows[ch]>1){//同一字符出现次数>1
char ch1 = s.charAt(left);
windows[ch1]--;//left指针右移,利用左指针移动清空win
left++;
}
max = Math.max(max,right-left+1);
}
return max;
}
}
二、最长递增子序列(输出字典序最小的)
【题目】:给定数组arr,设长度为n,输出arr的最长递增子序列。(如果有多个答案,请输出其中字典序最小的)
import java.util.*;
public class Solution {
public int[] LIS (int[] arr) {
if(arr == null || arr.length <= 0){
return null;
}
int len = arr.length;
int[] count = new int[len];// 存长度
int[] end = new int[len];// 存最长递增子序列
int index = 0;// end 数组下标
end[index] = arr[0];
count[0] = 1;
for(int i = 0; i < len; i++){
if(end[index] < arr[i]){
end[++index] = arr[i];
count[i] = index;
}else{
int left = 0, right = index;
while(left <= right){
int mid = (left + right) >> 1;
if(end[mid] >= arr[i]){
right = mid - 1;
}else{
left = mid + 1;
}
}
end[left] = arr[i];
count[i] = left;
}
}
//可能有多个答案,要求返回字典序最小的数组,所以从后向前遍历
int[] res = new int[index + 1];
for(int i = len - 1; i >= 0; i--){
if(count[i] == index){
res[index--] = arr[i];
}
}
return res;
}
}
三、最长连续序列
给定一个未排序的整数数组,找出最长连续序列的长度。
要求算法的时间复杂度为 O(n)。
示例:
输入: [100, 4, 200, 1, 3, 2]
输出: 4
解释: 最长连续序列是 [1, 2, 3, 4]。它的长度为 4。
【思路】
先遍历数组,将数字都存入到 HashSet 中便于在常量时间内找到值是否存在。然后再次遍历数组,当 set 中不存在 num-1 的时候,表示这是起点,然后寻找 num + 1, num + 2 … num + k 是否存在,更新结果即可。
class Solution {
public int longestConsecutive(int[] nums) {
int res = 0;
HashSet<Integer> set = new HashSet<>();
for(int num : nums) {
set.add(num);
}
for(int num : nums) {
if(!set.contains(num-1)) {
int curLen = 1;
while(set.contains(num + curLen)) {
curLen ++;
}
res = Math.max(res, curLen);
}
}
return res;
}
}