给定字符串str 。任务是找到str的最长子序列,使得子序列中所有相邻的字符都不同。
例子:
Input: str = “ababa”
Output: 5
Explanation:
“ababa” is the subsequence satisfying the condition
Input: str = “xxxxy”
Output: 2
Explanation:
“xy” is the subsequence satisfying the condition
方法一:贪心法
可以观察到,在给定字符串的最长子序列中,选择与先前选择的字符不相似的第一个字符,并且相邻字符不同。
这个想法是在遍历字符串时跟踪先前选择的字符,如果当前字符与前一个字符不同,则计算当前字符以找到最长的子序列。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the longest Subsequence
// with different adjacent character
int longestSubsequence(string s)
{
// Length of the string s
int n = s.length();
int answer = 0;
// Previously picked character
char prev = '-';
for (int i = 0; i < n; i++) {
// If the current character is
// different from the previous
// then include this character
// and update previous character
if (prev != s[i]) {
prev = s[i];
answer++;
}
}
return answer;
}
// Driver Code
int main()
{
string str = "ababa";
// Function call
cout << longestSubsequence(str);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to find the longest subsequence
// with different adjacent character
static int longestSubsequence(String s)
{
// Length of the String s
int n = s.length();
int answer = 0;
// Previously picked character
char prev = '-';
for(int i = 0; i < n; i++)
{
// If the current character is
// different from the previous
// then include this character
// and update previous character
if (prev != s.charAt(i))
{
prev = s.charAt(i);
answer++;
}
}
return answer;
}
// Driver Code
public static void main(String[] args)
{
String str = "ababa";
// Function call
System.out.print(longestSubsequence(str));
}
}
// This code is contributed by sapnasingh4991
Python3
# Python3 program for the above approach
# Function to find the longest Subsequence
# with different adjacent character
def longestSubsequence(s):
# Length of the string s
n = len(s);
answer = 0;
# Previously picked character
prev = '-';
for i in range(0, n):
# If the current character is
# different from the previous
# then include this character
# and update previous character
if (prev != s[i]):
prev = s[i];
answer += 1;
return answer;
# Driver Code
str = "ababa";
# Function call
print(longestSubsequence(str));
# This code is contributed by Code_Mech
C#
// C# program for the above approach
using System;
class GFG{
// Function to find the longest subsequence
// with different adjacent character
static int longestSubsequence(String s)
{
// Length of the String s
int n = s.Length;
int answer = 0;
// Previously picked character
char prev = '-';
for(int i = 0; i < n; i++)
{
// If the current character is
// different from the previous
// then include this character
// and update previous character
if (prev != s[i])
{
prev = s[i];
answer++;
}
}
return answer;
}
// Driver Code
public static void Main(String[] args)
{
String str = "ababa";
// Function call
Console.Write(longestSubsequence(str));
}
}
// This code is contributed by amal kumar choubey
Javascript
C++
// C++ program for the above approach
#include
using namespace std;
// dp table
int dp[100005][27];
// A recursive function to find the
// update the dp[][] table
int calculate(int pos, int prev, string& s)
{
// If we reach end of the string
if (pos == s.length()) {
return 0;
}
// If subproblem has been computed
if (dp[pos][prev] != -1)
return dp[pos][prev];
// Initialise variable to find the
// maximum length
int val = 0;
// Choose the current character
if (s[pos] - 'a' + 1 != prev) {
val = max(val,
1 + calculate(pos + 1,
s[pos] - 'a' + 1,
s));
}
// Omit the current character
val = max(val, calculate(pos + 1, prev, s));
// Return the store answer to the
// current subproblem
return dp[pos][prev] = val;
}
// Function to find the longest Subsequence
// with different adjacent character
int longestSubsequence(string s)
{
// Length of the string s
int n = s.length();
// Initialise the memoisation table
memset(dp, -1, sizeof(dp));
// Return the final ans after every
// recursive call
return calculate(0, 0, s);
}
// Driver Code
int main()
{
string str = "ababa";
// Function call
cout << longestSubsequence(str);
return 0;
}
Java
// Java program for the above approach
class GFG{
// dp table
static int dp[][] = new int[100005][27];
// A recursive function to find the
// update the dp[][] table
static int calculate(int pos, int prev, String s)
{
// If we reach end of the String
if (pos == s.length())
{
return 0;
}
// If subproblem has been computed
if (dp[pos][prev] != -1)
return dp[pos][prev];
// Initialise variable to find the
// maximum length
int val = 0;
// Choose the current character
if (s.charAt(pos) - 'a' + 1 != prev)
{
val = Math.max(val, 1 + calculate(pos + 1,
s.charAt(pos) - 'a' + 1,
s));
}
// Omit the current character
val = Math.max(val, calculate(pos + 1, prev, s));
// Return the store answer to the
// current subproblem
return dp[pos][prev] = val;
}
// Function to find the longest Subsequence
// with different adjacent character
static int longestSubsequence(String s)
{
// Length of the String s
int n = s.length();
// Initialise the memoisation table
for(int i = 0; i < 100005; i++)
{
for (int j = 0; j < 27; j++)
{
dp[i][j] = -1;
}
}
// Return the final ans after every
// recursive call
return calculate(0, 0, s);
}
// Driver Code
public static void main(String[] args)
{
String str = "ababa";
// Function call
System.out.print(longestSubsequence(str));
}
}
// This code is contributed by Rohit_ranjan
Python3
# Python3 program for the above approach
# dp table
dp = [[-1 for i in range(27)] for j in range(100005)];
# A recursive function to find the
# update the dp table
def calculate(pos, prev, s):
# If we reach end of the String
if (pos == len(s)):
return 0;
# If subproblem has been computed
if (dp[pos][prev] != -1):
return dp[pos][prev];
# Initialise variable to find the
# maximum length
val = 0;
# Choose the current character
if (ord(s[pos]) - ord('a') + 1 != prev):
val = max(val, 1 + calculate(pos + 1,
ord(s[pos]) -
ord('a') + 1, s));
# Omit the current character
val = max(val, calculate(pos + 1, prev, s));
# Return the store answer to
# the current subproblem
dp[pos][prev] = val;
return dp[pos][prev];
# Function to find the longest Subsequence
# with different adjacent character
def longestSubsequence(s):
# Length of the String s
n = len(s);
# Return the final ans after every
# recursive call
return calculate(0, 0, s);
# Driver Code
if __name__ == '__main__':
str = "ababa";
# Function call
print(longestSubsequence(str));
# This code is contributed by shikhasingrajput
C#
// C# program for the above approach
using System;
public class GFG{
// dp table
static int [,]dp = new int[100005,27];
// A recursive function to find the
// update the [,]dp table
static int calculate(int pos, int prev, String s)
{
// If we reach end of the String
if (pos == s.Length)
{
return 0;
}
// If subproblem has been computed
if (dp[pos,prev] != -1)
return dp[pos,prev];
// Initialise variable to
// find the maximum length
int val = 0;
// Choose the current character
if (s[pos] - 'a' + 1 != prev)
{
val = Math.Max(val, 1 +
calculate(pos + 1,
s[pos] - 'a' + 1,
s));
}
// Omit the current character
val = Math.Max(val, calculate(pos + 1, prev, s));
// Return the store answer to the
// current subproblem
return dp[pos,prev] = val;
}
// Function to find the longest Subsequence
// with different adjacent character
static int longestSubsequence(String s)
{
// Length of the String s
int n = s.Length;
// Initialise the memoisation table
for(int i = 0; i < 100005; i++)
{
for (int j = 0; j < 27; j++)
{
dp[i,j] = -1;
}
}
// Return the readonly ans after every
// recursive call
return calculate(0, 0, s);
}
// Driver Code
public static void Main(String[] args)
{
String str = "ababa";
// Function call
Console.Write(longestSubsequence(str));
}
}
// This code is contributed by shikhasingrajput
Javascript
输出:
5
时间复杂度: O(N),其中 N 是给定字符串的长度。
方法二:动态规划
- 对于给定字符串str 中的每个字符,执行以下操作:
- 为结果子序列选择字符串的当前字符,并为剩余的字符串重复查找结果子序列的下一个可能字符。
- 省略当前字符并重复剩余字符串以查找结果子序列的下一个可能字符。
- 上述递归调用中的最大值将是具有不同相邻元素的最长子序列。
- 递推关系由下式给出:
Let dp[pos][prev] be the length of longest subsequence
till index pos such that alphabet prev was picked previously.a dp[pos][prev] = max(1 + function(pos+1, s[pos] - 'a' + 1, s),
function(pos+1, prev, s));
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// dp table
int dp[100005][27];
// A recursive function to find the
// update the dp[][] table
int calculate(int pos, int prev, string& s)
{
// If we reach end of the string
if (pos == s.length()) {
return 0;
}
// If subproblem has been computed
if (dp[pos][prev] != -1)
return dp[pos][prev];
// Initialise variable to find the
// maximum length
int val = 0;
// Choose the current character
if (s[pos] - 'a' + 1 != prev) {
val = max(val,
1 + calculate(pos + 1,
s[pos] - 'a' + 1,
s));
}
// Omit the current character
val = max(val, calculate(pos + 1, prev, s));
// Return the store answer to the
// current subproblem
return dp[pos][prev] = val;
}
// Function to find the longest Subsequence
// with different adjacent character
int longestSubsequence(string s)
{
// Length of the string s
int n = s.length();
// Initialise the memoisation table
memset(dp, -1, sizeof(dp));
// Return the final ans after every
// recursive call
return calculate(0, 0, s);
}
// Driver Code
int main()
{
string str = "ababa";
// Function call
cout << longestSubsequence(str);
return 0;
}
Java
// Java program for the above approach
class GFG{
// dp table
static int dp[][] = new int[100005][27];
// A recursive function to find the
// update the dp[][] table
static int calculate(int pos, int prev, String s)
{
// If we reach end of the String
if (pos == s.length())
{
return 0;
}
// If subproblem has been computed
if (dp[pos][prev] != -1)
return dp[pos][prev];
// Initialise variable to find the
// maximum length
int val = 0;
// Choose the current character
if (s.charAt(pos) - 'a' + 1 != prev)
{
val = Math.max(val, 1 + calculate(pos + 1,
s.charAt(pos) - 'a' + 1,
s));
}
// Omit the current character
val = Math.max(val, calculate(pos + 1, prev, s));
// Return the store answer to the
// current subproblem
return dp[pos][prev] = val;
}
// Function to find the longest Subsequence
// with different adjacent character
static int longestSubsequence(String s)
{
// Length of the String s
int n = s.length();
// Initialise the memoisation table
for(int i = 0; i < 100005; i++)
{
for (int j = 0; j < 27; j++)
{
dp[i][j] = -1;
}
}
// Return the final ans after every
// recursive call
return calculate(0, 0, s);
}
// Driver Code
public static void main(String[] args)
{
String str = "ababa";
// Function call
System.out.print(longestSubsequence(str));
}
}
// This code is contributed by Rohit_ranjan
蟒蛇3
# Python3 program for the above approach
# dp table
dp = [[-1 for i in range(27)] for j in range(100005)];
# A recursive function to find the
# update the dp table
def calculate(pos, prev, s):
# If we reach end of the String
if (pos == len(s)):
return 0;
# If subproblem has been computed
if (dp[pos][prev] != -1):
return dp[pos][prev];
# Initialise variable to find the
# maximum length
val = 0;
# Choose the current character
if (ord(s[pos]) - ord('a') + 1 != prev):
val = max(val, 1 + calculate(pos + 1,
ord(s[pos]) -
ord('a') + 1, s));
# Omit the current character
val = max(val, calculate(pos + 1, prev, s));
# Return the store answer to
# the current subproblem
dp[pos][prev] = val;
return dp[pos][prev];
# Function to find the longest Subsequence
# with different adjacent character
def longestSubsequence(s):
# Length of the String s
n = len(s);
# Return the final ans after every
# recursive call
return calculate(0, 0, s);
# Driver Code
if __name__ == '__main__':
str = "ababa";
# Function call
print(longestSubsequence(str));
# This code is contributed by shikhasingrajput
C#
// C# program for the above approach
using System;
public class GFG{
// dp table
static int [,]dp = new int[100005,27];
// A recursive function to find the
// update the [,]dp table
static int calculate(int pos, int prev, String s)
{
// If we reach end of the String
if (pos == s.Length)
{
return 0;
}
// If subproblem has been computed
if (dp[pos,prev] != -1)
return dp[pos,prev];
// Initialise variable to
// find the maximum length
int val = 0;
// Choose the current character
if (s[pos] - 'a' + 1 != prev)
{
val = Math.Max(val, 1 +
calculate(pos + 1,
s[pos] - 'a' + 1,
s));
}
// Omit the current character
val = Math.Max(val, calculate(pos + 1, prev, s));
// Return the store answer to the
// current subproblem
return dp[pos,prev] = val;
}
// Function to find the longest Subsequence
// with different adjacent character
static int longestSubsequence(String s)
{
// Length of the String s
int n = s.Length;
// Initialise the memoisation table
for(int i = 0; i < 100005; i++)
{
for (int j = 0; j < 27; j++)
{
dp[i,j] = -1;
}
}
// Return the readonly ans after every
// recursive call
return calculate(0, 0, s);
}
// Driver Code
public static void Main(String[] args)
{
String str = "ababa";
// Function call
Console.Write(longestSubsequence(str));
}
}
// This code is contributed by shikhasingrajput
Javascript
输出:
5
时间复杂度: O(N),其中 N 是给定字符串的长度。
辅助空间: O(26*N) 其中 N 是给定字符串的长度。