Problem:

Given two strings S and T, determine if they are both one edit distance apart.

General Analysis:

This problem is not hard. However, to write out more efficient and elegant solution, we need to dive more deep to understand the logic behind it. 

Instant idea:
1. The length difference betweeen string "s" and string "t" must not longer than 1, otherwise, no one edit operation could make them same. (at least two insert or two delete actions)
2. For it is valid, it could be following cases:
2.1 s.length() == t.length()
s and t have only one character in difference. 2.2 s.length() == t.length() - 1 (s.length() < t.length())
a. insert one character into s.
b. append one charcter after s. Note: append one charcter after s is strange, it could easily break your solution!

Wrong Solution 1:

public class Solution {
public boolean isOneEditDistance(String s, String t) {
int s_len = s.length();
int t_len = t.length();
if (s_len == 0 && t_len == 0)
return false;
if (Math.abs(s_len - t_len) > 1) {
return false;
} else if(Math.abs(s_len - t_len) == 1) {
String longer = s;
String shorter = t;
if (s_len < t_len) {
longer = t;
shorter = s;
}
for (int i = 0; i < longer.length(); i++) {
String new_longer = longer.substring(0, i) + longer.substring(i+1);
if (new_longer.equals(shorter))
return true;
}
} else{
int diff_count = 0;
for (int i = 0; i < s_len; i++) {
if (s.charAt(i) != t.charAt(i))
diff_count++;
}
if (diff_count != 1)
return false;
}
return true;
}
}

Mistake Analysis:

Input:
"", ""
Output:
true
Expected:
false Mistakes:
The above solution must be wrong!!! How could you mixed "return false" and "return true" in the middle of code! It could easily break your logic.

Inefficient Solution 1:

public class Solution {
public boolean isOneEditDistance(String s, String t) {
int s_len = s.length();
int t_len = t.length();
if (s_len == 0 && t_len == 0)
return false;
if (Math.abs(s_len - t_len) > 1) {
return false;
} else if(Math.abs(s_len - t_len) == 1) {
String longer = s;
String shorter = t;
if (s_len < t_len) {
longer = t;
shorter = s;
}
for (int i = 0; i < longer.length(); i++) {
String new_longer = longer.substring(0, i) + longer.substring(i+1);
if (new_longer.equals(shorter))
return true;
}
} else{
int diff_count = 0;
for (int i = 0; i < s_len; i++) {
if (s.charAt(i) != t.charAt(i))
diff_count++;
}
if (diff_count == 1)
return true;
}
return false;
}
}

Analysis:

Even though the above solution was accepted, it is quite slow. Cause for the case of "s.length() == t.length() - 1", we have tried to delete each character in the t. which actually is quite uncessary!!!! 

What's more, I have a ugly code to assgin the longer and shorter string.
--------------------------------------------------------------
String longer = s;
String shorter = t;
if (s_len < t_len) {
longer = t;
shorter = s;
}
---------------------------------------------------------------
Which could be smartly written as
if (t_len < s_len)
return isOneEditDistance(t, s);
It means s is always the shorter String. Improve analysis:
Actually the above solution is really really ugly, we consturct a new string and make the compare every time. The efficiency is unacceptable! There actually could be a more easy way to do it!
We know we actually could only do two things to make two string equal, one is to insert a new character in to the shorter string s or replace one character in s. And the two actions were only allowed to perform once! Basic idea:
We compare the characters in s and t one by one. Once we detect a difference, we try to use following two ways to fix it.
1. insert the difference character into s.
String inserted = (s.substring(0, i) + t.charAt(i) + s.substring(i));
2. reaplce the character in s.
String replaced = (s.substring(0, i) + t.charAt(i) + s.substring(i+1)); If one of them works, it means we could use only one edit to make those two string equal. However if both of them fail, we should return false!!!<Since we only allowed to do one edit, and the conflict at current position could not be simply solved by one edit> In the case of there is no difference in common length part of s and t, we should also distinguish following two cases:
1. s == t, which should return false.
2. s == t + 1, which should return true, since we could append one character after s to make them same. while (i < s_len && j < t_len) {
if (s.charAt(i) != t.charAt(j)) {
...
return replaced.equals(t) || inserted.equals(t);
}
...
return s_len + 1 == t_len;

Efficient Solution 1:

public class Solution {
public boolean isOneEditDistance(String s, String t) {
int s_len = s.length();
int t_len = t.length();
if (t_len < s_len)
return isOneEditDistance(t, s);
if (t_len - s_len > 1)
return false;
int i = 0;
int j = 0;
while (i < s_len && j < t_len) {
if (s.charAt(i) != t.charAt(j)) {
String replaced = (s.substring(0, i) + t.charAt(i) + s.substring(i+1));
String inserted = (s.substring(0, i) + t.charAt(i) + s.substring(i));
return replaced.equals(t) || inserted.equals(t);
}
i++;
j++;
}
return s_len + 1 == t_len;
}
}

Improve Analysis:

The aove solution could be written in a more elegant way.
1. use only one index i, since until we return the result, i and j share the same start and pace.
int i = 0;
int j = 0;
while (i < s_len && j < t_len) {
...
i++;
j++;
} 2. no need to compare the suppposed common part among s and t.
String replaced = (s.substring(0, i) + t.charAt(i) + s.substring(i+1));
String inserted = (s.substring(0, i) + t.charAt(i) + s.substring(i));
return replaced.equals(t) || inserted.equals(t); Since s.substring(0, i) is common is s and t. any after the edits, t.charAt(i) was inserted/replaced into s. We absolutely have no need to compare them again.
if (s.charAt(i) != t.charAt(i))
return s.substring(i+1).equals(t.substring(i+1)) || s.substring(i).equals(t.substring(i+1));

Upgraded Solution:

public class Solution {
public boolean isOneEditDistance(String s, String t) {
int s_len = s.length();
int t_len = t.length();
if (t_len < s_len)
return isOneEditDistance(t, s);
if (t_len - s_len > 1)
return false;
int i = 0;
while (i < s_len) {
if (s.charAt(i) != t.charAt(i))
return s.substring(i+1).equals(t.substring(i+1)) || s.substring(i).equals(t.substring(i+1));
i++;
}
return s_len + 1 == t_len;
}
}

[LeetCode#161] One Edit Distance的更多相关文章

  1. [LeetCode] 161. One Edit Distance 一个编辑距离

    Given two strings s and t, determine if they are both one edit distance apart. Note: There are 3 pos ...

  2. [leetcode]161. One Edit Distance编辑步数为一

    Given two strings s and t, determine if they are both one edit distance apart. Note: There are 3 pos ...

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

    Given two strings S and T, determine if they are both one edit distance apart. 给定两个字符串,判断他们是否是一步变换得到 ...

  4. 【LeetCode】161. One Edit Distance

    Difficulty: Medium  More:[目录]LeetCode Java实现 Description Given two strings S and T, determine if the ...

  5. 161. One Edit Distance

    题目: Given two strings S and T, determine if they are both one edit distance apart. 链接: http://leetco ...

  6. [LeetCode] 161. One Edit Distance_Medium

    Given two strings s and t, determine if they are both one edit distance apart. Note: There are 3 pos ...

  7. 【Leetcode】72 Edit Distance

    72. Edit Distance Given two words word1 and word2, find the minimum number of steps required to conv ...

  8. [LC] 161. One Edit Distance

    Given two strings s and t, determine if they are both one edit distance apart. Note: There are 3 pos ...

  9. leetcode@ [72/115] Edit Distance & Distinct Subsequences (Dynamic Programming)

    https://leetcode.com/problems/edit-distance/ Given two words word1 and word2, find the minimum numbe ...

随机推荐

  1. cookie和session可能需要知道的知识

    做Android程序员,了解服务器的知识是相当重要的,比如cookie和session. 首先介绍一点背景知识,我们知道HTTP的连接是无状态的,HTTPS只是增加了安全,有了SSL证书来验证,作为服 ...

  2. 解决OOM小记

    跟猜想的一样是OOM.一回来遇一不怎么熟悉的sb,给我气的....算了.....哥哥也是种种原因回的合肥.继续看问题. 这个地方的界面是这样的 划红线的地方是三个LinearLayout,每次oncl ...

  3. iOS imagePicker使用方法,方便使用!三步轻松搞定!

    自己总结的修改头像的方法,只为方便自己查询使用!转发 步骤:1.遵守代理协议 <UIImagePickerControllerDelegate,UINavigationControllerDel ...

  4. Spring配置,JDBC数据源及事务

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  5. spring Aop 注解

    个人理解: spring Aop 是什么:面向切面编程,类似于自定义拦截操作,支持拦截之前操作@Before,拦截之后操作@After,拦截环绕操作@Around. 什么情况下使用spring Aop ...

  6. swift基本语法

    swift种语法着实怪异,实质干的事情还是一样的,一下将对此语法做简单介绍: 1.swift语法种已经剔除“:”这个结束符号,下面将演示入门操作的hello world import Foundati ...

  7. tp_shop解读1

    由于想弄一个商城,因此研究了一下tp_shop,这个据说能完成几乎所有的功能. 考虑到原有的例子过于复杂,因此把所有相关的数据都删除了,结果上来就出错了,查了两天,大致弄清楚了状况. 关于错误的原因 ...

  8. sar监控系统状态

    sar 命令很强大,它可以监控系统所有资源状态,比如平均负载.网卡流量.磁盘状态.内存使用等等. 它不同于其他系统状态监控工具的地方在于,它可以打印历史信息,可以显示当天从零点开始到当前时刻的系统状态 ...

  9. jQuery学习 day01

    最近受某大牛指点(我不会说他姓范),了解了一下jQuery,据说很牛X,就了解了一下,第一天,分享给大家一些心得吧. 1.首先就是导入jQuery文件了,这里我是去jQuery官网下载的.(大家可以去 ...

  10. js stringObject的indexOf方法

    我所写的这个是基本知识的基本知识,为什么我还是要写呢,所谓说好记性不如烂比头,作为一名前端开发人员,太多相似的代码见的又太多,但是又不常见,所以很容易忘记,那我把indexOf原理讲清楚 indexO ...