返回介绍

solution / 2500-2599 / 2573.Find the String with LCP / README_EN

发布于 2024-06-17 01:03:04 字数 9076 浏览 0 评论 0 收藏 0

2573. Find the String with LCP

中文文档

Description

We define the lcp matrix of any 0-indexed string word of n lowercase English letters as an n x n grid such that:

  • lcp[i][j] is equal to the length of the longest common prefix between the substrings word[i,n-1] and word[j,n-1].

Given an n x n matrix lcp, return the alphabetically smallest string word that corresponds to lcp. If there is no such string, return an empty string.

A string a is lexicographically smaller than a string b (of the same length) if in the first position where a and b differ, string a has a letter that appears earlier in the alphabet than the corresponding letter in b. For example, "aabd" is lexicographically smaller than "aaca" because the first position they differ is at the third letter, and 'b' comes before 'c'.

 

Example 1:

Input: lcp = [[4,0,2,0],[0,3,0,1],[2,0,2,0],[0,1,0,1]]
Output: "abab"
Explanation: lcp corresponds to any 4 letter string with two alternating letters. The lexicographically smallest of them is "abab".

Example 2:

Input: lcp = [[4,3,2,1],[3,3,2,1],[2,2,2,1],[1,1,1,1]]
Output: "aaaa"
Explanation: lcp corresponds to any 4 letter string with a single distinct letter. The lexicographically smallest of them is "aaaa". 

Example 3:

Input: lcp = [[4,3,2,1],[3,3,2,1],[2,2,2,1],[1,1,1,3]]
Output: ""
Explanation: lcp[3][3] cannot be equal to 3 since word[3,...,3] consists of only a single letter; Thus, no answer exists.

 

Constraints:

  • 1 <= n == lcp.length ==lcp[i].length <= 1000
  • 0 <= lcp[i][j] <= n

Solutions

Solution 1: Greedy + Construction

Since the constructed string requires the lexicographically smallest order, we can start by filling the string $s$ with the character 'a'.

If the current position $i$ has not been filled with a character, then we can fill the character 'a' at position $i$. Then we enumerate all positions $j > i$. If $lcp[i][j] > 0$, then position $j$ should also be filled with the character 'a'. Then we add one to the ASCII code of the character 'a' and continue to fill the remaining unfilled positions.

After filling, if there are unfilled positions in the string, it means that the corresponding string cannot be constructed, so we return an empty string.

Next, we can enumerate each position $i$ and $j$ in the string from large to small, and then judge whether $s[i]$ and $s[j]$ are equal:

  • If $s[i] = s[j]$, at this time we need to judge whether $i$ and $j$ are the last positions of the string. If so, then $lcp[i][j]$ should be equal to $1$, otherwise $lcp[i][j]$ should be equal to $0$. If the above conditions are not met, it means that the corresponding string cannot be constructed, so we return an empty string. If $i$ and $j$ are not the last positions of the string, then $lcp[i][j]$ should be equal to $lcp[i + 1][j + 1] + 1$, otherwise it means that the corresponding string cannot be constructed, so we return an empty string.
  • Otherwise, if $lcp[i][j] > 0$, it means that the corresponding string cannot be constructed, so we return an empty string.

If every position in the string meets the above conditions, then we can construct the corresponding string and return it.

The time complexity is $O(n^2)$, and the space complexity is $O(n)$. Where $n$ is the length of the string.

class Solution:
  def findTheString(self, lcp: List[List[int]]) -> str:
    n = len(lcp)
    s = [""] * n
    i = 0
    for c in ascii_lowercase:
      while i < n and s[i]:
        i += 1
      if i == n:
        break
      for j in range(i, n):
        if lcp[i][j]:
          s[j] = c
    if "" in s:
      return ""
    for i in range(n - 1, -1, -1):
      for j in range(n - 1, -1, -1):
        if s[i] == s[j]:
          if i == n - 1 or j == n - 1:
            if lcp[i][j] != 1:
              return ""
          elif lcp[i][j] != lcp[i + 1][j + 1] + 1:
            return ""
        elif lcp[i][j]:
          return ""
    return "".join(s)
class Solution {
  public String findTheString(int[][] lcp) {
    int n = lcp.length;
    char[] s = new char[n];
    int i = 0;
    for (char c = 'a'; c <= 'z'; ++c) {
      while (i < n && s[i] != '\0') {
        ++i;
      }
      if (i == n) {
        break;
      }
      for (int j = i; j < n; ++j) {
        if (lcp[i][j] > 0) {
          s[j] = c;
        }
      }
    }
    for (i = 0; i < n; ++i) {
      if (s[i] == '\0') {
        return "";
      }
    }
    for (i = n - 1; i >= 0; --i) {
      for (int j = n - 1; j >= 0; --j) {
        if (s[i] == s[j]) {
          if (i == n - 1 || j == n - 1) {
            if (lcp[i][j] != 1) {
              return "";
            }
          } else if (lcp[i][j] != lcp[i + 1][j + 1] + 1) {
            return "";
          }
        } else if (lcp[i][j] > 0) {
          return "";
        }
      }
    }
    return String.valueOf(s);
  }
}
class Solution {
public:
  string findTheString(vector<vector<int>>& lcp) {
    int i = 0, n = lcp.size();
    string s(n, '\0');
    for (char c = 'a'; c <= 'z'; ++c) {
      while (i < n && s[i]) {
        ++i;
      }
      if (i == n) {
        break;
      }
      for (int j = i; j < n; ++j) {
        if (lcp[i][j]) {
          s[j] = c;
        }
      }
    }
    if (s.find('\0') != -1) {
      return "";
    }
    for (i = n - 1; ~i; --i) {
      for (int j = n - 1; ~j; --j) {
        if (s[i] == s[j]) {
          if (i == n - 1 || j == n - 1) {
            if (lcp[i][j] != 1) {
              return "";
            }
          } else if (lcp[i][j] != lcp[i + 1][j + 1] + 1) {
            return "";
          }
        } else if (lcp[i][j]) {
          return "";
        }
      }
    }
    return s;
  }
};
func findTheString(lcp [][]int) string {
  i, n := 0, len(lcp)
  s := make([]byte, n)
  for c := 'a'; c <= 'z'; c++ {
    for i < n && s[i] != 0 {
      i++
    }
    if i == n {
      break
    }
    for j := i; j < n; j++ {
      if lcp[i][j] > 0 {
        s[j] = byte(c)
      }
    }
  }
  if bytes.IndexByte(s, 0) >= 0 {
    return ""
  }
  for i := n - 1; i >= 0; i-- {
    for j := n - 1; j >= 0; j-- {
      if s[i] == s[j] {
        if i == n-1 || j == n-1 {
          if lcp[i][j] != 1 {
            return ""
          }
        } else if lcp[i][j] != lcp[i+1][j+1]+1 {
          return ""
        }
      } else if lcp[i][j] > 0 {
        return ""
      }
    }
  }
  return string(s)
}
function findTheString(lcp: number[][]): string {
  let i: number = 0;
  const n: number = lcp.length;
  let s: string = '\0'.repeat(n);
  for (let ascii = 97; ascii < 123; ++ascii) {
    const c: string = String.fromCharCode(ascii);
    while (i < n && s[i] !== '\0') {
      ++i;
    }
    if (i === n) {
      break;
    }
    for (let j = i; j < n; ++j) {
      if (lcp[i][j]) {
        s = s.substring(0, j) + c + s.substring(j + 1);
      }
    }
  }
  if (s.indexOf('\0') !== -1) {
    return '';
  }
  for (i = n - 1; ~i; --i) {
    for (let j = n - 1; ~j; --j) {
      if (s[i] === s[j]) {
        if (i === n - 1 || j === n - 1) {
          if (lcp[i][j] !== 1) {
            return '';
          }
        } else if (lcp[i][j] !== lcp[i + 1][j + 1] + 1) {
          return '';
        }
      } else if (lcp[i][j]) {
        return '';
      }
    }
  }
  return s;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文