[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 ...
随机推荐
- Windows 7中,用Visual Studio开发WPF应用程序,实现从Windows Explorer中拖拽文件到应用程序,始终显示“无法拖放”符号问题解决方案
Are you running your application or Visual Studio that hosts the app under administrative privilege? ...
- Android版本分布——2016年10月更新
Code Name Version API Level Distribution frogy(冻酸奶) 2.2.x 8 0.1% gingerbread(姜饼) 2.3.3——2.3.7 10 2.0 ...
- Haproxy配置参数
HAProxy配置中分成五部分内容,当然这些组件不是必选的,可以根据需要选择部分作为配置. ===================== global 参数是进程级的,通常和操作系统(OS)相关. ...
- dbms_job涉及到的知识点
用于安排和管理作业队列,通过使用作业,可以使ORACLE数据库定期执行特定的任务. 一.dbms_job涉及到的知识点1.创建job:variable jobno number;dbms_job.su ...
- javascript调用oc的方法
1.引入#import <JavaScriptCore/JavaScriptCore.h> 2.JSContext *jsContext = [self.webView valueForK ...
- 09.13随笔2014年9月13日22:32:38,奶爸的英语教室,groovy
我们这里只推荐一本语法书:台湾的旋元佑老师写的<文法俱乐部>(简体版名为<语法俱乐部>).这本书因为出版社倒闭而绝版,淘宝可以买到影印的版本. (1)学英语到 奶爸的英语教室 ...
- Hdu 4514 湫湫系列故事——设计风景线
湫湫系列故事--设计风景线 Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Total ...
- c++ primer复习(四)
1 标准库容器 顺序容器:vector.list.deque 容器适配器:stack.queue.priority_queue 2 容器元素类型约束: 容器元素类型必须支持复制和赋值,因为容器存放的都 ...
- 九度OJ 1084 整数拆分
题目地址:http://ac.jobdu.com/problem.php?pid=1084 题目描述: 一个整数总可以拆分为2的幂的和,例如: 7=1+2+4 7=1+2+2+2 7=1+1+1+4 ...
- 二进制方式快速安装MySQL数据库命令集合
二进制方式快速安装MySQL数据库命令集合 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1.安装mysql ls mysql ...