递增序列相关题型
首先子序列和子数组的概念是不一样的。
比如:int[] nums={1,2,4,3,5,4,7,2};
子数组:
递增序列相关题型(LeetCode)
LeetCode 1800 最大升序子数组和
- 题目:求升序子数组中,和最大是多少
- 代码:
public int maxAscendingSum(int[] nums) {
if (nums==null||nums.length==0)
return 0;
int max =nums[0];
int cur =nums[0];
for (int i = 1; i < nums.length ; i++) {
if (nums[i]>nums[i-1]){
cur=cur+nums[i];
max=Math.max(max,cur);
}else {
cur=nums[i];
}
}
return max;
}
LeetCode 674 最长连续递增子数组
- 题目:求最长的子数组的长度
- 思路:双指针,一个指针用来记录,连续子数组的起点,另外一个指针用做遍历。
- 代码
public int findLengthOfLCIS(int[] nums) {
if (nums==null||nums.length==0){
return 0;
}
int left =0;
int max =1;
for (int i = 1; i < nums.length ; i++) {
if (nums[i]>nums[i-1]){
max=Math.max(max,i-left+1);
}else {
left=i;
}
}
return max;
}
LeetCode 300 最长递增子序列
- 题目:最长递增子序列的个数
- 思路:动态规划
dp[i]=Math.max(dp[i],dp[j]+1);
dp[i]表示,下标为i时,最长的递增序列的个数 - 代码:
public int lengthOfLIS(int[] nums) {
if (nums==null||nums.length==0)
return 0;
int[] dp =new int[nums.length];
Arrays.fill(dp,1);
int max=1;
for (int i = 0; i < nums.length ; i++) {
for (int j = 0; j <i ; j++) {
if (nums[j]<nums[i]){
dp[i]=Math.max(dp[i],dp[j]+1);
max =Math.max(max,dp[i]);
}
}
}
return max;
}
LeetCode 1143 最长公共子序列
- 题目:求两个字符串中,最长的公共子序列
- 思路:二维dp,可以自己模拟一下流程,就很好理解解法了
- 代码:
public int longestCommonSubsequence(String text1, String text2) {
if (text1==null||text2==null){
return 0;
}
int m=text1.length();
int n=text2.length();
int[][] dp = new int[m+1][n+1];
for (int i =1; i <=m ; i++) {
for (int j = 1; j <=n ; j++) {
if (text1.charAt(i-1)==text2.charAt(j-1)){
dp[i][j]=dp[i-1][j-1]+1;
}else {
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
return dp[m][n];
}
LeetCode 583 两个字符串的删除操作
- 题目:每次可以删除两个字符串的任意一个字符,使得两个字符串相同。
- 思路:求两个字符串最长公共子序列,然后每个字符串删除非最长公共子序列的元素。两个字符串长度分别为m,n,那么解法是:m+n-2*(最长公共子序列)
- 代码:
public int minDistance(String word1, String word2) {
if (word1==null||word2==null)
return 0;
int m=word1.length();
int n = word2.length();
int[][] dp = new int[m+1][n+1];
for (int i = 1; i <=m ; i++) {
for (int j = 1; j <=n ; j++) {
if (word1.charAt(i-1)==word2.charAt(j-1))
dp[i][j]=dp[i-1][j-1]+1;
else
dp[i][j]=Math.max(dp[i][j-1],dp[i-1][j]);
}
}
return m+n-2*dp[m][n];
}
LeetCode 718 最长重复子数组
- 题目:求两个数组,最长的,连续的子数组的个数
- 思路:和最长公共子序列差不多,只不过不需要记录不相等的情况
- 代码:
public int findLength(int[] A, int[] B) {
if (A==null||B==null){
return 0;
}
int m=A.length;
int n=B.length;
int[][] dp = new int[m+1][n+1];
int max =0;
for (int i = 1; i <=m ; i++) {
for (int j = 1; j <=n ; j++) {
if (A[i-1]==B[j-1]){
dp[i][j]=dp[i-1][j-1]+1;
max=Math.max(max,dp[i][j]);
}
}
}
return max;
}
LeetCode 392 判断子序列
- 题目:判断一个字符串是否是另外一个一个字符串的子序列
- 思路:使用双指针对两个字符串遍历
- 代码:
public boolean isSubsequence(String s, String t) {
int left=0;
int right=0;
while (left!=s.length()&&right!=t.length()){
if (s.charAt(left)==t.charAt(right)){
left++;
right++;
}else {
right++;
}
}
return left==s.length();
}
LeetCode 673 最长递增子序列的个数
- 这个题有点难,据说是线段树
LeetCode 3 无重复最长子串
- 求无重复的最长子串
- 双指针+set集合,有两种方法,一种是for循环作为右指针,一种是作为左指针。两种方法各有千秋。其实也提供一种双指针遍历的方法
- 代码:
for循环作为右指针
public int lengthOfLongestSubstring(String s) {
if (s==null||s.length()==0){
return 0;
}
Set<Character> set = new HashSet<>();
int left=0;
int max =0;
for (int i = 0; i < s.length(); i++) {
if (set.isEmpty()||!set.contains(s.charAt(i))){
set.add(s.charAt(i));
max=Math.max(max,i-left+1);
}else {
for (int j = left; j <i ; j++) {
set.remove(s.charAt(j));
if (s.charAt(j)==s.charAt(i)){
set.add(s.charAt(i));
left=j+1;
break;
}
}
}
}
return max;
}
for循环作为左指针
public int lengthOfLongestSubstring(String s) {
if (s==null||s.length()==0){
return 0;
}
Set<Character> set = new HashSet<>();
int right=0;
int max =0;
for (int i = 0; i < s.length() ; i++) {
if (i!=0){
set.remove(s.charAt(i-1));
}
while (right<s.length() && !set.contains(s.charAt(right))){
set.add(s.charAt(right++));
max=Math.max(max,right-i);
}
}
return max;
}
LeetCode 128 最长连续序列
- 题目:无序且重复,最长递增子序列
- 思路:最简单,去重,排序,最长递增子序列。最优,map去重,然后递归
- 代码:
public int longestConsecutive(int[] nums) {
Map<Integer,Integer> map = new HashMap<>();
for (int num : nums){
map.put(num,1);
}
for (int num : nums){
forword(map,num);
}
return count(map);
}
public int forword(Map<Integer,Integer> map,int num){
if(!map.containsKey(num))
return 0;
int cnt = map.get(num);
if (cnt>1)
return cnt;
cnt = forword(map,num+1)+1;
map.put(num,cnt);
return cnt;
}
public int count(Map<Integer,Integer> map){
int longest = 0;
for (Integer num : map.keySet()){
longest = Math.max(longest,map.get(num));
}
return longest;
}