返回介绍

solution / 0800-0899 / 0854.K-Similar Strings / README_EN

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

854. K-Similar Strings

中文文档

Description

Strings s1 and s2 are k-similar (for some non-negative integer k) if we can swap the positions of two letters in s1 exactly k times so that the resulting string equals s2.

Given two anagrams s1 and s2, return the smallest k for which s1 and s2 are k-similar.

 

Example 1:

Input: s1 = "ab", s2 = "ba"
Output: 1
Explanation: The two string are 1-similar because we can use one swap to change s1 to s2: "ab" --> "ba".

Example 2:

Input: s1 = "abc", s2 = "bca"
Output: 2
Explanation: The two strings are 2-similar because we can use two swaps to change s1 to s2: "abc" --> "bac" --> "bca".

 

Constraints:

  • 1 <= s1.length <= 20
  • s2.length == s1.length
  • s1 and s2 contain only lowercase letters from the set {'a', 'b', 'c', 'd', 'e', 'f'}.
  • s2 is an anagram of s1.

Solutions

Solution 1

class Solution:
  def kSimilarity(self, s1: str, s2: str) -> int:
    def next(s):
      i = 0
      while s[i] == s2[i]:
        i += 1
      res = []
      for j in range(i + 1, n):
        if s[j] == s2[i] and s[j] != s2[j]:
          res.append(s2[: i + 1] + s[i + 1 : j] + s[i] + s[j + 1 :])
      return res

    q = deque([s1])
    vis = {s1}
    ans, n = 0, len(s1)
    while 1:
      for _ in range(len(q)):
        s = q.popleft()
        if s == s2:
          return ans
        for nxt in next(s):
          if nxt not in vis:
            vis.add(nxt)
            q.append(nxt)
      ans += 1
class Solution {
  public int kSimilarity(String s1, String s2) {
    Deque<String> q = new ArrayDeque<>();
    Set<String> vis = new HashSet<>();
    q.offer(s1);
    vis.add(s1);
    int ans = 0;
    while (true) {
      for (int i = q.size(); i > 0; --i) {
        String s = q.pollFirst();
        if (s.equals(s2)) {
          return ans;
        }
        for (String nxt : next(s, s2)) {
          if (!vis.contains(nxt)) {
            vis.add(nxt);
            q.offer(nxt);
          }
        }
      }
      ++ans;
    }
  }

  private List<String> next(String s, String s2) {
    int i = 0, n = s.length();
    char[] cs = s.toCharArray();
    for (; cs[i] == s2.charAt(i); ++i) {
    }

    List<String> res = new ArrayList<>();
    for (int j = i + 1; j < n; ++j) {
      if (cs[j] == s2.charAt(i) && cs[j] != s2.charAt(j)) {
        swap(cs, i, j);
        res.add(new String(cs));
        swap(cs, i, j);
      }
    }
    return res;
  }

  private void swap(char[] cs, int i, int j) {
    char t = cs[i];
    cs[i] = cs[j];
    cs[j] = t;
  }
}
class Solution {
public:
  int kSimilarity(string s1, string s2) {
    queue<string> q{{s1}};
    unordered_set<string> vis{{s1}};
    int ans = 0;
    while (1) {
      for (int i = q.size(); i; --i) {
        auto s = q.front();
        q.pop();
        if (s == s2) {
          return ans;
        }
        for (auto& nxt : next(s, s2)) {
          if (!vis.count(nxt)) {
            vis.insert(nxt);
            q.push(nxt);
          }
        }
      }
      ++ans;
    }
  }

  vector<string> next(string& s, string& s2) {
    int i = 0, n = s.size();
    for (; s[i] == s2[i]; ++i) {}
    vector<string> res;
    for (int j = i + 1; j < n; ++j) {
      if (s[j] == s2[i] && s[j] != s2[j]) {
        swap(s[i], s[j]);
        res.push_back(s);
        swap(s[i], s[j]);
      }
    }
    return res;
  }
};
func kSimilarity(s1 string, s2 string) int {
  next := func(s string) []string {
    i := 0
    res := []string{}
    for ; s[i] == s2[i]; i++ {
    }
    for j := i + 1; j < len(s1); j++ {
      if s[j] == s2[i] && s[j] != s2[j] {
        res = append(res, s[:i]+string(s[j])+s[i+1:j]+string(s[i])+s[j+1:])
      }
    }
    return res
  }

  q := []string{s1}
  vis := map[string]bool{s1: true}
  ans := 0
  for {
    for i := len(q); i > 0; i-- {
      s := q[0]
      q = q[1:]
      if s == s2 {
        return ans
      }
      for _, nxt := range next(s) {
        if !vis[nxt] {
          vis[nxt] = true
          q = append(q, nxt)
        }
      }
    }
    ans++
  }
}

Solution 2

class Solution:
  def kSimilarity(self, s1: str, s2: str) -> int:
    def f(s):
      cnt = sum(c != s2[i] for i, c in enumerate(s))
      return (cnt + 1) >> 1

    def next(s):
      i = 0
      while s[i] == s2[i]:
        i += 1
      res = []
      for j in range(i + 1, n):
        if s[j] == s2[i] and s[j] != s2[j]:
          res.append(s2[: i + 1] + s[i + 1 : j] + s[i] + s[j + 1 :])
      return res

    q = [(f(s1), s1)]
    dist = {s1: 0}
    n = len(s1)
    while 1:
      _, s = heappop(q)
      if s == s2:
        return dist[s]
      for nxt in next(s):
        if nxt not in dist or dist[nxt] > dist[s] + 1:
          dist[nxt] = dist[s] + 1
          heappush(q, (dist[nxt] + f(nxt), nxt))
class Solution {
  public int kSimilarity(String s1, String s2) {
    PriorityQueue<Pair<Integer, String>> q
      = new PriorityQueue<>(Comparator.comparingInt(Pair::getKey));
    q.offer(new Pair<>(f(s1, s2), s1));
    Map<String, Integer> dist = new HashMap<>();
    dist.put(s1, 0);
    while (true) {
      String s = q.poll().getValue();
      if (s.equals(s2)) {
        return dist.get(s);
      }
      for (String nxt : next(s, s2)) {
        if (!dist.containsKey(nxt) || dist.get(nxt) > dist.get(s) + 1) {
          dist.put(nxt, dist.get(s) + 1);
          q.offer(new Pair<>(dist.get(nxt) + f(nxt, s2), nxt));
        }
      }
    }
  }

  private int f(String s, String s2) {
    int cnt = 0;
    for (int i = 0; i < s.length(); ++i) {
      if (s.charAt(i) != s2.charAt(i)) {
        ++cnt;
      }
    }
    return (cnt + 1) >> 1;
  }

  private List<String> next(String s, String s2) {
    int i = 0, n = s.length();
    char[] cs = s.toCharArray();
    for (; cs[i] == s2.charAt(i); ++i) {
    }

    List<String> res = new ArrayList<>();
    for (int j = i + 1; j < n; ++j) {
      if (cs[j] == s2.charAt(i) && cs[j] != s2.charAt(j)) {
        swap(cs, i, j);
        res.add(new String(cs));
        swap(cs, i, j);
      }
    }
    return res;
  }

  private void swap(char[] cs, int i, int j) {
    char t = cs[i];
    cs[i] = cs[j];
    cs[j] = t;
  }
}
using pis = pair<int, string>;

class Solution {
public:
  int kSimilarity(string s1, string s2) {
    priority_queue<pis, vector<pis>, greater<pis>> q;
    q.push({f(s1, s2), s1});
    unordered_map<string, int> dist;
    dist[s1] = 0;
    while (1) {
      auto [_, s] = q.top();
      q.pop();
      if (s == s2) {
        return dist[s];
      }
      for (auto& nxt : next(s, s2)) {
        if (!dist.count(nxt) || dist[nxt] > dist[s] + 1) {
          dist[nxt] = dist[s] + 1;
          q.push({dist[nxt] + f(nxt, s2), nxt});
        }
      }
    }
  }

  int f(string& s, string& s2) {
    int cnt = 0;
    for (int i = 0; i < s.size(); ++i) {
      cnt += s[i] != s2[i];
    }
    return (cnt + 1) >> 1;
  }

  vector<string> next(string& s, string& s2) {
    int i = 0, n = s.size();
    for (; s[i] == s2[i]; ++i) {}
    vector<string> res;
    for (int j = i + 1; j < n; ++j) {
      if (s[j] == s2[i] && s[j] != s2[j]) {
        swap(s[i], s[j]);
        res.push_back(s);
        swap(s[i], s[j]);
      }
    }
    return res;
  }
};
func kSimilarity(s1 string, s2 string) int {
  next := func(s string) []string {
    i := 0
    res := []string{}
    for ; s[i] == s2[i]; i++ {
    }
    for j := i + 1; j < len(s1); j++ {
      if s[j] == s2[i] && s[j] != s2[j] {
        res = append(res, s[:i]+string(s[j])+s[i+1:j]+string(s[i])+s[j+1:])
      }
    }
    return res
  }

  f := func(s string) int {
    cnt := 0
    for i := range s {
      if s[i] != s2[i] {
        cnt++
      }
    }
    return (cnt + 1) >> 1
  }

  q := hp{pair{f(s1), s1}}
  dist := map[string]int{s1: 0}
  for {
    s := heap.Pop(&q).(pair).s
    if s == s2 {
      return dist[s]
    }
    for _, nxt := range next(s) {
      if v, ok := dist[nxt]; !ok || v > dist[s]+1 {
        dist[nxt] = dist[s] + 1
        heap.Push(&q, pair{dist[nxt] + f(nxt), nxt})
      }
    }
  }
}

type pair struct {
  v int
  s string
}
type hp []pair

func (h hp) Len() int { return len(h) }
func (h hp) Less(i, j int) bool {
  a, b := h[i], h[j]
  return a.v < b.v
}
func (h hp) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *hp) Push(v any)   { *h = append(*h, v.(pair)) }
func (h *hp) Pop() any   { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v }

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

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

发布评论

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