📌  相关文章
📜  具有相邻字符的最长子序列

📅  最后修改于: 2021-04-26 05:26:59             🧑  作者: Mango

给定字符串str 。任务是找到最长的str子序列,以使子序列中彼此相邻的所有字符都不同。
例子:

方法1:贪婪的方法
可以观察到的是选择第一字符是不相似的给定的给定的字符串与不同的相邻的字符的最长子序列中先前选择的字符。
这个想法是在遍历字符串时跟踪先前选择的字符,如果当前字符与先前的字符不同,则对当前字符进行计数以找到最长的子序列。
下面是上述方法的实现:

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


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


输出:
5





时间复杂度: O(N),其中N是给定字符串的长度。
方法2:动态编程

  1. 对于给定字符串str中的每个字符,请执行以下操作:
    • 为结果子序列选择字符串的当前字符,然后为剩余的字符串重复出现,以找到结果子序列的下一个可能字符。
    • 忽略当前字符,然后对剩余的字符串重复进行操作,以找到所产生的子序列的下一个可能的字符。
  2. 上述递归调用中的最大值将是相邻元素不同的最长子序列。
  3. 递归关系由下式给出:
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

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
输出:
5





时间复杂度: O(N),其中N是给定字符串的长度。
辅助空间: O(26 * N),其中N是给定字符串的长度。