320. Generalized Abbreviation
最后更新
三刷
13-Jan-2017
貌似像DFS。
String做法里有一种思想,每个char都可以选择考虑或者不考虑。
这里考虑就是缩减为数字; 不考虑就是把前面有的数字先加了,再以当前为缩减起始位置。。
所以你得有2个pointer一个记录缩减的数量,另一个记录指针在字符串中的位置。
public class Solution {
public List<String> generateAbbreviations(String word) {
List<String> res = new ArrayList<>();
if (word.length() == 0) return res;
dfs(res, word, 0, 0, new StringBuilder());
return res;
}
public void dfs(List<String> res, String s, int index, int len, StringBuilder sb) {
int tempLen = sb.length();
if (index == s.length()) {
if (len != 0) sb.append(len);
res.add(sb.toString());
} else {
dfs(res, s, index+1, len+1, sb);
if (len != 0) sb.append(len);
dfs(res, s, index+1, 0, sb.append(s.charAt(index)));
}
sb.setLength(tempLen);
}
}
09-Nov-2016
首先想到的是遍历,对于每个单词的字母都遍历,比如
spy: 1py,s1y,sp1
然后每个遍历完的单词再遍历。。左右有数字就合并比如
1py: 11py=>2py, 1p1
这样。。
但是单词长了会出现重复,于是又加了一个SET判断重复,毕竟不是在构造前就判断重复,所以估计会TLE。
结果居然AC了。
public class Solution {
public List<String> generateAbbreviations(String word)
{
List<String> res = new ArrayList<String>();
Set<String> set = new HashSet<String>();
if(word.length() == 0)
{
res.add("");
return res;
}
if(word.length() == 1)
{
res.add(word);
res.add("1");
return res;
}
tonightTheMusicSeemsSoLoud(res,word,set);
return res;
}
public void tonightTheMusicSeemsSoLoud(List<String> res, String word, Set<String> set)
{
if(set.contains(word)) return;
res.add(word);
set.add(word);
for(int i = 0; i < word.length();i++)
{
if(word.charAt(i) < '0' || word.charAt(i) > '9')
{
String tempWord = maybeItsBetterThisWay(i,word);
tonightTheMusicSeemsSoLoud(res,new String(tempWord),set);
}
}
}
// replace letter with number
public String maybeItsBetterThisWay(int m, String word)
{
//System.out.println(m + " " + word);
int l = m - 1;
int r = m + 1;
int lNum = 0;
int rNum = 0;
int pow = 1;
while(l >= 0 && word.charAt(l) >= '0' && word.charAt(l) <= '9')
{
lNum = (word.charAt(l)-'0')*pow + lNum;
pow*=10;
l--;
}
while(r < word.length() && word.charAt(r) >= '0' && word.charAt(r) <= '9')
{
rNum = rNum*10 + word.charAt(r) - '0';
r++;
}
int val = lNum + rNum + 1;
String res = "";
if(l < 0 && r >= word.length()) res = Integer.toString(val);
else if(l < 0) res = Integer.toString(val) + word.substring(r);
else if(r >= word.length()) res = word.substring(0,l+1) + Integer.toString(val);
else res = word.substring(0,l+1) + Integer.toString(val) + word.substring(r);
//System.out.println(res);
return res;
}
}
耗时220ms。。据统计,该数据被98%的人羞辱。。。
感觉问题出在重复上,比如
s2 2p 1p1
这3个单词下一步的结果都是3。。
如果单词很长重复的情况会更多。
。。经过一番思考。。
在纸上写了一下 发现了一个规律
比如在改变fey的时候顺序是这样的
fey - 1ey - 2y - 3
fey - f1y - f2
fey - fe1
一开始的思路是所有单词都尝试把每一个letter换成1,然后和左右合并成digit。
现在不用尝试每一个letter,只从第一个数字开始,比如:
本来f1y是按顺序从头尝试替换f和y,现在从里面的1开始,只需要替换y就行了,就避免了重复。同理,fe1不按顺序替换f,e,从第一个数字1开始替换,发现1后面没了,直接停止就行了。。避免了重复。。
在原来基础上修改一下,去掉检查重复的SET,加1个变量记录开始位置。
public class Solution {
public List<String> generateAbbreviations(String word)
{
List<String> res = new ArrayList<String>();
//Set<String> set = new HashSet<String>();
if(word.length() == 0)
{
res.add("");
return res;
}
if(word.length() == 1)
{
res.add(word);
res.add("1");
return res;
}
tonightTheMusicSeemsSoLoud(res,word,0);
return res;
}
public void tonightTheMusicSeemsSoLoud(List<String> res, String word,int m)
{
res.add(word);
for(int i = m; i < word.length();i++)
{
if(word.charAt(i) < '0' || word.charAt(i) > '9')
{
String tempWord = maybeItsBetterThisWay(i,word);
tonightTheMusicSeemsSoLoud(res,new String(tempWord),i);
}
}
}
// replace letter with number
public String maybeItsBetterThisWay(int m, String word)
{
//System.out.println(m + " " + word);
int l = m - 1;
int r = m + 1;
int lNum = 0;
int rNum = 0;
int pow = 1;
while(l >= 0 && word.charAt(l) >= '0' && word.charAt(l) <= '9')
{
lNum = (word.charAt(l)-'0')*pow + lNum;
pow*=10;
l--;
}
while(r < word.length() && word.charAt(r) >= '0' && word.charAt(r) <= '9')
{
rNum = rNum*10 + word.charAt(r) - '0';
r++;
}
int val = lNum + rNum + 1;
String res = "";
if(l < 0 && r >= word.length()) res = Integer.toString(val);
else if(l < 0) res = Integer.toString(val) + word.substring(r);
else if(r >= word.length()) res = word.substring(0,l+1) + Integer.toString(val);
else res = word.substring(0,l+1) + Integer.toString(val) + word.substring(r);
//System.out.println(res);
return res;
}
}
25ms..只战胜了33%。。。
似乎想不出什么好办法。。先这样了,看看别人怎么做的。
二刷。
这个题抄袭了别人的做法。
(https://discuss.leetcode.com/topic/32765/java-14ms-beats-100)
主要是剥离出一个模型比较困难。
每到一个位置都可以选择是否转化为数字。
准地说是选择马上转化还是晚点转化:
晚点转化的话需要记住有个字母要转化,积累的个数。
马上转化就把积累的个数一起转化了(或者根本就没有要转化的,积累个数是0的时候),然后积累个数清0.
有点绕的。
T(n) = 2T(n-1) + 2T(n-2)...2T(1) + 乱七八糟的常熟运算
T(n-1) = 2T(n-2)...2T(1)
T(n) = 6T(n-1)
Time Complexity: O(6^n) 是这样么。。
Space Complexity: O(6^n)
public class Solution {
public List<String> generateAbbreviations(String word) {
List<String> res = new ArrayList<>();
dfs(res, word.toCharArray(), new StringBuilder(), 0, 0);
return res;
}
public void dfs(List<String> res, char[] word, StringBuilder s, int pos, int num) {
int len = s.length();
if (word.length == pos) {
if (num != 0) s.append(num);
res.add(s.toString());
} else {
// not change
dfs(res, word, s, pos+1, num+1);
if (num != 0) {
s.append(num);
}
s.append(word[pos]);
dfs(res, word, s, pos+1, 0);
}
s.setLength(len);
}
}
320. Generalized Abbreviation的更多相关文章
- LeetCode 320. Generalized Abbreviation
原题链接在这里:https://leetcode.com/problems/generalized-abbreviation/ 题目: Write a function to generate the ...
- 【LeetCode】320. Generalized Abbreviation 解题报告 (C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS 日期 题目地址:https://leetcod ...
- [LeetCode] Generalized Abbreviation 通用简写
Write a function to generate the generalized abbreviations of a word. Example: Given word = "wo ...
- LeetCode Generalized Abbreviation
原题链接在这里:https://leetcode.com/problems/generalized-abbreviation/ 题目: Write a function to generate the ...
- [Locked] Generalized Abbreviation
Write a function to generate the generalized abbreviations of a word. Example:Given word = "wor ...
- [Swift]LeetCode320. 通用简写 $ Generalized Abbreviation
Write a function to generate the generalized abbreviations of a word. Example: Given word = "wo ...
- LeetCode All in One 题目讲解汇总(持续更新中...)
终于将LeetCode的免费题刷完了,真是漫长的第一遍啊,估计很多题都忘的差不多了,这次开个题目汇总贴,并附上每道题目的解题连接,方便之后查阅吧~ 477 Total Hamming Distance ...
- LeetCode题目按公司分类
LinkedIn(39) 1 Two Sum 23.0% Easy 21 Merge Two Sorted Lists 35.4% Easy 23 Merge k Sorted Lists 23.3% ...
- LeetCode All in One题解汇总(持续更新中...)
突然很想刷刷题,LeetCode是一个不错的选择,忽略了输入输出,更好的突出了算法,省去了不少时间. dalao们发现了任何错误,或是代码无法通过,或是有更好的解法,或是有任何疑问和建议的话,可以在对 ...
随机推荐
- ACM YTU 2018 母牛的故事
母牛的故事 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...
- mouseover和mouseout事件在鼠标经过子元素时也会触发
JavaScript的mouseover和mouseout事件,在绑定元素内部有子元素的情况下, 经过绑定元素时会多次触发mouseover和mouseout事件. jQuery解决办法: jquer ...
- Android中UI线程与后台线程交互设计的5种方法
我想关于这个话题已经有很多前辈讨论过了.今天算是一次学习总结吧. 在android的设计思想中,为了确保用户顺滑的操作体验.一 些耗时的任务不能够在UI线程中运行,像访问网络就属于这类任务.因此我们必 ...
- 【微机】验证负数以补码存储程序 C语言
微机中验证负数以补码存储程序 一.相关基础知识 负数的补码等于它的反码加1,即在其反码的最低位加1就为该数的补码,且在计算机中负数以补码形式进行存储. .int型占4字节(32位二进制)char型占1 ...
- 完美方案——iOS的WebView自适应内容高度
/////////////////////////////初始化,self.view是父控件///////////////////////////////// _webView = [[UIWebVi ...
- 面试cookie
cookie : 存储数据,当用户访问了某个网站(网页)的时候,我们就可以通过cookie来像访问者电脑上存储数据 1.不同的浏览器存放的cookie位置不一样,也是不能通用的 2.cookie的存储 ...
- 运行从别处复制过来的linux可执行程序
1, 首先ldd看看缺不缺so文件,如果不缺可忽略下面的文字,直接执行 2, 先看看缺的这些库在系统上有没有,这些库可通过安装开发包,第三方软件进行安装 3, 找到可能会包含这些库的可执行程序,ldd ...
- spm使用之二兼谈spm的贱格
上一篇还没写完, 因为我觉得太长了, 影响阅读, 就截断继续写. 因为还没有写到修改 创建模块的模板啊. 之所以想到要修改spm用来创建模块的模板, 是因为, 有一天我突然上不了网了, 发现spm完全 ...
- bzoj 2594: [Wc2006]水管局长数据加强版 动态树
2594: [Wc2006]水管局长数据加强版 Time Limit: 25 Sec Memory Limit: 128 MBSubmit: 934 Solved: 291[Submit][Sta ...
- Contest 20140708 testB dp 组合数
testB 输入文件: testB.in 输出文件testB.out 时限3000ms 问题描述: 定义这样一个序列(a1,b1),(a2,b2),…,(ak,bk)如果这个序列是方序列的话必须满足 ...