Skip to main content
Back to problems
#2901
Medium Algorithms

Longest unequal adjacent groups subsequence ii

Array String Dynamic Programming
51.5% acceptance
Feb 25, 2026
573
168
You are given a string array words, and an array groups, both arrays having length n. The hamming distance between two strings of equal length is the number of positions at which the corresponding characters are different. You need to select the longest subsequence from an array of indices [0, 1, ..., n - 1], such that for the subsequence denoted as [i0, i1, ..., ik-1] having length k, the following holds: For adjacent indices in the subsequence, their corresponding groups are unequal, i.e., groups[ij] != groups[ij+1], for each j where 0 < j + 1 < k. words[ij] and words[ij+1] are equal in length, and the hamming distance between them is 1, where 0 < j + 1 < k, for all indices in the subsequence. Return a string array containing the words corresponding to the indices (in order) in the selected subsequence. If there are multiple answers, return any of them. Note: strings in words may be unequal in length.

Solution

Rust
Time O(n²)
Space O(n)
LeetCode
solution.rs
impl Solution {
  pub fn get_words_in_longest_subsequence(words: Vec<String>, groups: Vec<i32>) -> Vec<String> {
    let n = words.len();
    let mut dp = vec![1usize; n];
    let mut prev = vec![usize::MAX; n];

    fn hamming(a: &[u8], b: &[u8]) -> usize {
      a.iter().zip(b.iter()).filter(|(x, y)| x != y).count()
    }

    let mut best_end = 0;
    for i in 1..n {
      for j in 0..i {
        let wi = words[i].as_bytes();
        let wj = words[j].as_bytes();
        if groups[i] != groups[j] && wi.len() == wj.len() && hamming(wi, wj) == 1 {
          if dp[j] + 1 > dp[i] {
            dp[i] = dp[j] + 1;
            prev[i] = j;
          }
        }
      }
      if dp[i] > dp[best_end] {
        best_end = i;
      }
    }

    let mut result = Vec::new();
    let mut cur = best_end;
    loop {
      result.push(words[cur].clone());
      if prev[cur] == usize::MAX { break; }
      cur = prev[cur];
    }
    result.reverse();
    result
  }
}