给定两个字符串, 判断最少经过多少次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. 关于python merge后数据行数增加的问题

    其中一个可能的原因是 join 的 data 里面的列不唯一,也就是要匹配的表里面有些一行数据对应了被匹配表多条数据,这样出来可能会增加行数,可以再查一下被匹配表里的数据是否去重

  2. CSIC_716_20191109【函数的语法,以及函数的分类,可变长参数*args】

    函数 定义.作用.及使用方式 函数是一种工具,可以被重复调用. 使用函数可精简重复代码,减少冗余,增加代码的可读性. 函数要先构造函数,然后调用函数. 构造及调用函数的语法结构 关键字def  函数名 ...

  3. leetcode-63-不同路径②

    题目描述: 第一次提交: class Solution: def uniquePathsWithObstacles(self, obstacleGrid) : m = len(obstacleGrid ...

  4. [JZOJ2866] 【集训队互测 2012】Bomb

    题目 题目大意 给你一个有\(n\)个点的平面. 选择三个点,求两两之间曼哈顿距离和的最大值和最小值. 思考历程&正解 比赛的时候没有想太多,但感觉似乎比较水-- 首先有个很显然的性质,答案为 ...

  5. div中内容可左右上下滑动

    在<table>外套一层<div>,并且声明overflow:scroll属性,如: <div style="width:1620px;height:680px ...

  6. Mac+VS Code+Git+Github

    https://blog.csdn.net/qq_37747262/article/details/81750417

  7. pinmap 和 pin allocation

    串口管脚分配

  8. PAT甲级——A1120 Friend Numbers【20】

    Two integers are called "friend numbers" if they share the same sum of their digits, and t ...

  9. python pywin32学习笔记

    参考博客链接 https://blog.csdn.net/polyhedronx/article/details/81988948 参考博客链接 https://www.cnblogs.com/zha ...

  10. Post Office IOI 2000 /// 区间DP oj24077

    题目大意: 给定n个村庄的坐标,两个村庄之间的距离是其坐标之差的绝对值 最多能选m个村庄设立邮局,求设立邮局的地点使得各村庄与邮局距离总和最小 一, 所有的村庄看做在一条直线上 考虑三个因素:i 当前 ...