给定两个字符串, 判断最少经过多少次swap 可以使得 两个字符串一致,

首先类似的问题 是存在一个 underlying graph 的。

每一个字母都对应着一个节点,两个字符串的不一致表示为图上的一条有向边

最后的问题转化为 图上的最(多)圆环分解

要注意的是贪心策略并不能解决问题(即每一次都选择 最小的那个圆环构成原图)

1

使用记忆化搜索策略。

将一个所有可能存在路径存在与否的向量作为相应的状态

超时的代码

class Solution:
def kSimilarity(self, A, B):
"""
:type A: str
:type B: str
:rtype: int
"""
if (A==B):
return 0 N = len(A)
alp ='abcdef' pairs = [(a,b) for a in alp for b in alp if a!=b]
# 所有可能的路径 index = {p:i for i,p in enumerate(pairs)}
# 所有可能的路径的编号 count = [0]*len(index)
#可能路径的数目(原图) 也就是初始状态 for a,b in zip(A,B):
if(a!=b):
count[index[(a,b)]]= count[index[a,b]]+ 1 seen = set()
#所有可能出现的环
for size in range(2,len(alp) + 1):
for cand in itertools.permutations(alp,size):
# 最小的哪一个出发节点为是顺序(防止重复)
i = cand.index(min(cand))
seen.add (cand[i:]+cand[:i]) possibles = [] #所有可能的环的路径表示 状态之间的 路径 for cand in seen:
row = [0] * len(alp)*(len(alp)-1)
for a,b in zip(cand,cand[1:]+cand[:1]):
row[index[a,b]]= row[index[a,b]]+1 possibles.append(row)
ZERO = tuple([0]*len(row))
memo = {ZERO:0} # print(possibles)
def solve(count):
if count in memo :
return memo[count]
ans =float('-inf')
#所有可能的路径
for row in possibles :
count2 = list(count)
for i,x in enumerate(row):
if count2[i]>=x :
count2[i] = count2[i] - x
else:
break
else:
ans = max(ans,1 + solve(tuple(count2)))
memo[count]= ans
return ans return sum(count)-solve(tuple(count))

2 暴力进行广度优先搜索

因为可以证明最优解可以是永远更换第一个不匹配的字母到合适的位置,那么我可以将一个节点的边数目由 N2 下降到N

而并不是所有意义上的交换 这种复杂度降低是非常有必要的

结论: 这种数据量比较小的问题往往比较复杂,尤其可能没有多项式解

class Solution:
def kSimilarity(self, A, B):
"""
:type A: str
:type B: str
:rtype: int
"""
def nei(S):
for i,c in enumerate(S):
if c!= B[i]:
break T=list(S)
for j in range(i+1,len(S)):
if(S[j]==B[i]):
T[i],T[j]= T[j],T[i]
yield "".join(T)
T[j],T[i]=T[i],T[j] queue= collections.deque([A])
seen ={A:0}
while(queue):
S=queue.popleft()
if(S==B):
return seen[S]
for T in nei(S):
if T not in seen:
seen[T]=seen[S]+1
queue.append(T)

这里有一个 fiield 迭代器的用发 可以学习一个

leetcode 854. K-Similar Strings的更多相关文章

  1. [LeetCode] 854. K-Similar Strings 相似度为K的字符串

    Strings A and B are K-similar (for some non-negative integer K) if we can swap the positions of two ...

  2. [链表]LeetCode 25 K组一个翻转链表

    LeetCode 25 k组一个翻转链表 TITLE 示例 1: 输入:head = [1,2,3,4,5], k = 2 输出:[2,1,4,3,5] 示例 2: 输入:head = [1,2,3, ...

  3. 【LeetCode】1400. 构造 K 个回文字符串 Construct K Palindrome Strings

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 统计奇数字符出现次数 日期 题目地址:https:// ...

  4. Baozi Leetcode Solution 205: Isomorphic Strings

    Problem Statement Given two strings s and t, determine if they are isomorphic. Two strings are isomo ...

  5. [LeetCode] 555. Split Concatenated Strings 分割串联字符串

    Given a list of strings, you could concatenate these strings together into a loop, where for each st ...

  6. 【LeetCode】43. Multiply Strings 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  7. [LeetCode] Remove K Digits 去掉K位数字

    Given a non-negative integer num represented as a string, remove k digits from the number so that th ...

  8. [LeetCode] Find K Pairs with Smallest Sums 找和最小的K对数字

    You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k. Define ...

  9. [LeetCode] Top K Frequent Elements 前K个高频元素

    Given a non-empty array of integers, return the k most frequent elements. For example,Given [1,1,1,2 ...

随机推荐

  1. Image 释放

    你是用 Image.FromFile取的图片吧,这个方法会锁定图片文件. 有几种方法解决:一:System.Drawing.Image img = System.Drawing.Image.FromF ...

  2. Java 多线程 - 创建线程的方法 + Executors.newXXXThreadPool()缺点

    java中创建线程的三种方法以及区别: https://www.cnblogs.com/3s540/p/7172146.html 通过Executor 的工具类,创建三种类型的普通线程池: https ...

  3. 【JZOJ6273】欠钱

    description analysis 读懂题就可知\(b\)的收益即为\(a\)到\(b\)这一条链上边权的最小值 那么就是动态维护一个森林,询问链上最小值,同时必须满足儿子走向父亲 明显\(LC ...

  4. kubernetes忘记token或者token过期怎么加入k8s集群

    1.先查看token是否还可用 [root@hadoop01 ~]# kubeadm token list 1.1) 还在则获取ca证书sha256编码hash值,不在则进行2操作 openssl x ...

  5. DNS的解析过程

    1.什么是DNS 在互联网上,唯一标识一台计算机的是IP地址,但是IP地址不方便记忆,通过一个域名对应一个IP地址,来达到找到IP地址的目的,那么DNS就是将域名转换成IP地址的过程. 2.DNS查询 ...

  6. 20175323《Java程序设计》第三周学习总结

    教材学习内容总结 这周开始用幕布记录学习过程和思路,下面是我这章的知识框架总结https://mubu.com/doc/aNMW9Clym0 教材学习中的问题和解决过程 问题1:教材90页的Trian ...

  7. 获取AndroidManifest.xml中的meta-data元素

    android 开发中: 在AndroidManifest.xml中,<meta-data>元素可以作为子元素, 被包含在<activity>.<application& ...

  8. day 65 Django基础十一之认证系统

    Django基础十一之认证系统   本节目录 一 auth模块 二 User对象 三 扩展默认的auth_user表 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 auth模块 我们 ...

  9. 20.multi_case06

    # coding:utf-8 import asyncio # 通过create_task()方法 async def a(t): print('-->', t) await asyncio.s ...

  10. Arrays.asList()使用的问题

    在java语言中,把数组转换成List集合,有个很方便的方法就是 List<String> list = Arrays.asList("a","b" ...