判断两个字符串的edit distance为1

from https://leetcode.com/problems/one-edit-distance/

正如摘要所说,edit distance是通过变换某些位置的字符使得两个字符串相同的操作数;而该问题是一个比较有名的动态规划问题;分别用s和t表示两个字符串,s(i) 表示s中得第i个字符;用f(i, j)表示s(i)和t(j)的edit distance;那么有以下的递推关系:

f(i, j) = min (

f(i - 1, j) + 1; //即删掉s中得第i个字符;

f(i, j - 1) + 1; //即删掉t中得第j个字符;

f(i - 1, j - 1); //如果s(i) == t(j)

f(i - 1, j - 1) + 1; //s(i) != t(j), 所以要做一次替换;

)

所以第一种方案是先计算出所给两个字符串的edit distance,检查是否等于1;当然,这样做会超时,因为通过动态规划计算edit distance的时间复杂度为O(m * n);

但这里还是给出动态规划的代码:

public static int minDistance(String word1, String word2) {
    if (word1 == null || word1.length() == 0) {
        return word2 == null ? 0 : word2.length();
    }

    if (word2 == null || word2.length() == 0) {
        return word1.length();
    }

    char[] ss = word1.toCharArray();
    char[] ts = word2.toCharArray();

    int[][] m = new int[ss.length + 1][ts.length + 1];

    for (int i = 0; i < m.length; i++) {
        m[i][0] = i;
    }

    for (int j = 0; j < m[0].length; j++) {
        m[0][j] = j;
    }

    for (int i = 1; i < m.length; i++) {
        for (int j = 1; j < m[i].length; j++) {
            int a = m[i - 1][j - 1];
            if (ss[i - 1] != ts[j - 1]) {
                a += 1;
            }

            int b = m[i - 1][j] + 1;
            int c = m[i][j - 1] + 1;
            m[i][j] = Math.min(a, Math.min(b, c));
        }
    }

    return m[ss.length][ts.length];
}

其实还是要利用题目中要求的edit distance为1的条件,依次分析以下两个字符串的情况:

  1. 如果两个字符串的长度相差多于1,则肯定为false,因为至少需要删除两次字符;
  2. 如果两个字符串的长度相同,那么两个字符串中只能有一个位置的字符不同;这种情况只需要扫描一次就可以了;
  3. 如果两个字符串的长度相差1,假设s比t长,那么除了s中得某个位置,删掉该字符后,剩余部分应该完全相同;

似乎第三种情况比较难处理,事实上并非如此;依次检查s中得字符,假设处理到了位置i,那么可以知道位置i之前的字符s和t中都是相同的,否则的花,s和t中之前如果已经有一个字符不同的话,edit distance已经至少为1了;如果位置s(i) == t(i), 那么继续处理下一个字符,如果s(i) != t(i), 需要在t的i位置插入一个字符,然后检查剩余的字符是否相同即可;所以,第三种处理也只需要扫描一次;

public boolean isOneEditDistance(String s, String t) {
    int m = s.length();
    int n = t.length();
    if (m == n) {
        return checkSameLength(s.toCharArray(), t.toCharArray());
    } else if (m - n == 1) {
        return checkDiffLength(s.toCharArray(), t.toCharArray());
    } else if (n - m == 1) {
        return checkDiffLength(t.toCharArray(), s.toCharArray());
    } else {
        return false;
    }
}

private boolean checkDiffLength(char[] s, char[] t) {
    for(int i = 0; i < s.length; i++) {
        if(i == t.length) {
            return true;
        }

        if(s[i] == t[i]) {
            continue;
        }

        for(int j = i + 1; j < s.length; j++) {
            if(s[j] != t[j - 1]) {
                return false;
            }
        }
        return true;
    }

    return false;
}

private boolean checkSameLength(char[] s, char[] t) {
    int dist = 0;
    for (int i = 0; i < s.length; i++) {
        if (s[i] != t[i]) {
            dist += 1;
        }
        if (dist > 1) {
            return false;
        }
    }

    return dist == 1;
}
时间: 2024-12-24 23:34:28

判断两个字符串的edit distance为1的相关文章

判断两个字符串是否是变位词 (keep it up)

写一个函数判断两个字符串是否是变位词.变位词(anagrams)指的是组成两个单词的字符相同,但位置不同的单词.比如说, abbcd和abcdb就是一对变位词 这也是简单的题. 我们可以排序然后对比, 也可以直接统计字符出现的个数来判断.这里给出统计字符来判断的代码: bool isAnagram1(const string& vLeft, const string& vRight) { if (vLeft.size() != vRight.size()) return false; in

JavaSE8基础 String equalsIgnoreCase 判断两个字符串的内容是否相同 (不区分大小写)

os :windows7 x64    jdk:jdk-8u131-windows-x64    ide:Eclipse Oxygen Release (4.7.0)        code: package jizuiku.t02; public class Demo { public static void main(String[] args) { // 判断两个字符串的内容相同吗 不区分大小写 String s1 = "jizuiku"; String s2 = "a

java中判断两个字符串是否相等的问题

我最近刚学java,今天编程的时候就遇到一个棘手的问题,就是关于判断两个字符串是否相等的问题.在编程中,通常比较两个字符串是否相同的表达式是"==",但在java中不能这么写.在java中,用的是equals(); 例:A字符串和B和字符串比较: if(A.equals(B)){ } 返回true 或false. String 的equals 方法用于比较两个字符串是否相等.由于字符串是对象类型,所以不能用简单的"=="判断.而使用equals比较两个对象的内容是否

JavaSE8基础 String equals 判断两个字符串的内容是否相同(区分大小写)

os :windows7 x64    jdk:jdk-8u131-windows-x64    ide:Eclipse Oxygen Release (4.7.0)        code: package jizuiku.t02; public class Demo { public static void main(String[] args) { // 判断两个字符串的内容相同吗 String s1 = "jizuiku"; String s2 = "abcdef&q

[算法]判断两个字符串是否由相同的字符组成

如何判断两个字符串是否由相同的字符组成 题目描述: 由相同的字符组成是指组成两个字符串的字母以及各个字母的个数是一样的,只是排列顺序不同而已.例如"aaaabbc"与"abcbaaa"就由相同的字符组成的. 方法一: 排序法,将两个字符串中的字符排序,比较两个排序后的字符串是否相等.若相等则表明它们是由相同的字符组成的,否则,表明他们是由不同的字符组成的. import java.util.Arrays; public class Solution { public

【字符串】判断两个字符串是否由相同的字符组成

1 import java.util.Arrays; 2 import java.util.Scanner; 3 4 /** 5 * 功能:判断两个字符串是否由相同的字符组成,比如aaaabbc和abcbaaa就是. 6 * 思路1:将两个字符串按字符进行排序,判断排序后字符串是否相同: 7 * 思路2:申请一个256大小的int数组,遍历第一个字符串,遇到一个字符,就将字符对应的数组下标的元素+1,然后,遍历第二个字符串,同理-1,最后,判断数组的所有元素是否都是0. 8 */ 9 publi

字符串问题----判断两个字符串是否互为变形词

判断两个字符串是否互为变形词 给定两个字符串 str1 和str2 ,如果两个字符串中出现的字符种类一样,次数也一样,则互为变形词,实现一个函数判断两个字符串是否互为变形词.例如 str1="123",str2="132",true; str1="123",str2="1332",false; [解题思路] 1. 首先比较两个字符串的长度,长度不同肯定是false. 2. 如果长度相同,新建一个数组,用以存储每个字符出现次数.

leetcode 161. One Edit Distance 判断两个字符串是否是一步变换 --------- java

Given two strings S and T, determine if they are both one edit distance apart. 给定两个字符串,判断他们是否是一步变换得到的. 在这里需要注意几点: 1.不等于1的变换都要返回false(包括变换次数等于0). 2.还有很多细节需要注意. 方法如下: 1.直接判断:1)如果差值大于1,直接返回false.  2)如果长度相同,那么依次判断,是否只有一个字母不一样.  3)如果不一样,那么看是否是只是多出了一个字母. p

[leetcode]242. Valid Anagram判断两个字符串是不是包含相同字符的重排列

/* 思路是判断26个字符在两个字符串中出现的次数是不是都一样,如果一样就返回true. 记住这个方法 */ if (s.length()!=t.length()) return false; int[] words = new int[26]; for (int i = 0; i < s.length(); i++) { words[s.charAt(i)-'a']++; words[t.charAt(i)-'a']--; } for (int i = 0; i < 26; i++) { i