[LeetCode#161] One Edit Distance
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的更多相关文章
- [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 ...
- [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 ...
- ✡ leetcode 161. One Edit Distance 判断两个字符串是否是一步变换 --------- java
Given two strings S and T, determine if they are both one edit distance apart. 给定两个字符串,判断他们是否是一步变换得到 ...
- 【LeetCode】161. One Edit Distance
Difficulty: Medium More:[目录]LeetCode Java实现 Description Given two strings S and T, determine if the ...
- 161. One Edit Distance
题目: Given two strings S and T, determine if they are both one edit distance apart. 链接: http://leetco ...
- [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 ...
- 【Leetcode】72 Edit Distance
72. Edit Distance Given two words word1 and word2, find the minimum number of steps required to conv ...
- [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 ...
- 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 ...
随机推荐
- java中关于时间的格式化
long time = System.currentTimeMillis(); SimpleDateFormat format = new SimpleDateFormat(); String s = ...
- IOS中的NSTimer定时器详解
/* 在IOS中有多种定时器,这里我对NSTimer定时器做了一个简单的介绍.如果你是小白,你可能会从这篇文章中学习到一些知识,如果你是大牛,请别吝啬你的评论,指出我的不足,你的质疑是对我最大的帮助. ...
- sublimeText3中 less2css error: `lessc` is not available的解决办法
昨天在sublimeText3中安装了less 以及 less2css插件,但是在编译保存的时候总是出现错误: less2css error: `lessc` is not available 就go ...
- bzoj1090:[SCOI2003]字符串折叠
思路:区间dp,令f[l][r]表示l到r的答案,于是f[l][r]=min(f[l][mid],f[mid+1][r]),如果能折叠f[l][r]=min(f[l][r],f[l][l+len-1] ...
- 自己动手丰衣足食,h5手机端jquery弹窗插件(事件冒泡、单例模式、遮盖部分禁止默认滚动)
感谢浏览,欢迎交流=.= 公司开发微信网页多处需要使用弹窗,使用jquery-ui的定制化下载仍需要150多kb,想来有些奢侈(最终下来只有11kb,压缩后2kb,啊,我的神), 手机端弹窗方式与pc ...
- 如何在Ubuntu上创建及管理LXC容器?
将LXC安装到Ubuntu上 $ sudo apt-get install lxc 安装完毕之后,运行lxc-checkconifg工具,检查当前Linux内核支持LXC的情况.要是一切都已被启用,内 ...
- mui H5 js动态添加不同类型的数据
html页面需要添加的页面的数据格式 <ul class="mui-table-view" id="OA_task_1"> <li class ...
- js json和对象互相转换
http://www.jb51.net/article/44562.htm obj = JSON.parse(string) | obj = jQuery.parseJSON(str) 将JSON字符 ...
- 基于smarty+medoo手搭php简单的框架
1.首先看一下搭建好的smarty目录(箭头位置是后新建的文件夹,也是框架结构的最终目录结构) 2.首先在根目录下新建index.php文件即入口文件,内容如下 <?phprequire_onc ...
- ObjectCopy
对象的传参用的是传引用,但开发中通常不允许对传入参数进行修改.因此对象拷贝很常用,Python提供一个很方便的对象拷贝方法 如代码: __author__ = 'mengxuan' import co ...