您的位置:首页 > 产品设计 > UI/UE

leetcode题解-28. Implement strStr() && 521. Longest Uncommon Subsequence I && 522 II

2017-11-12 15:54 555 查看
先看第一道题目,实现内置的strStr()函数:

Implement strStr().

Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.

Example 1:

Input: haystack = "hello", needle = "ll"
Output: 2
Example 2:

Input: haystack = "aaaaa", needle = "bba"
Output: -1


其实就是判断一个字符串是否为另一个字符串的子串,并找到其开始索引。我们使用遍历法和内置函数两种方法来实现:

//5%,使用substring和startswith两个内置函数实现,效率比较低
public int strStr(String haystack, String needle) {
if(needle.equals(""))
return 0;
for(int i=0; i<haystack.length(); i++){
if(haystack.substring(i).startsWith(needle))
return i;
}
return -1;
}

//48%,然后我又使用遍历的方法,判断是否为子串。如果将haystack和needle两个字符串转化成char[]数组,效率会有所提升,达到68%
public static int strStr1(String haystack, String needle){
if(needle.equals(""))
return 0;
for(int i=0; i<=haystack.length() - needle.length(); i++){
if(haystack.charAt(i) == needle.charAt(0)){
int j=1;
while(j<needle.length() && haystack.charAt(i+j) == needle.charAt(j)) j++;
if(j == needle.length()) return i;
}
}
return -1;
}

//28%,disscuss中看到的一种解法,直接两个循环,但效率较低
public int strStr2(String haystack, String needle) {
for (int i = 0; ; i++) {
for (int j = 0; ; j++) {
if (j == needle.length()) return i;
if (i + j == haystack.length()) return -1;
if (needle.charAt(j) != haystack.charAt(i + j)) break;
}
}
}


521&&522,Longest Uncommon Subsequence,题目如下所示:

Given a group of two strings, you need to find the longest uncommon subsequence of this group of two strings. The longest uncommon subsequence is defined as the longest subsequence of one of these strings and this subsequence should not be any subsequence of the other strings.

A subsequence is a sequence that can be derived from one sequence by deleting some characters without changing the order of the remaining elements. Trivially, any string is a subsequence of itself and an empty string is a subsequence of any string.

The input will be two strings, and the output needs to be the length of the longest uncommon subsequence. If the longest uncommon subsequence doesn't exist, return -1.

================================521============================================
Example 1:
Input: "aba", "cdc"
Output: 3
Explanation: The longest uncommon subsequence is "aba" (or "cdc"),
because "aba" is a subsequence of "aba",
but not a subsequence of any other strings in the group of two strings.
Note:

Both strings' lengths will not exceed 100.
Only letters from a ~ z will appear in input strings.

================================522============================================

Example 1:
Input: "aba", "cdc", "eae"
Output: 3
Note:

All the given strings' lengths will not exceed 10.
The length of the given list will be in the range of [2, 50].


两道题目定义相同,不同之处就在于第一个题目输入的是两个字符串,而第二个题目输入的是一个字符串数组,然后寻找其最长的非公共字符串。第一个题目很简单,因为如果两个字符串不想等的话,那么结果一定是长度较大的那一个==不明白这道题目的本意是个啥,然后第二道题目进行扩展,变成了一个数组,思路一样,我们就是要找到不同且长度最大的字符串即可。先看521的代码,就一行没什么好说的:

public int findLUSlength(String a, String b) {
return a.equals(b) ? -1 : Math.max(a.length(), b.length());
}


然后看522的解法,首先我们要将数组中的所有的字符串按照其长度进行排序,这样从长到短挨个进行判断,如果最长的那个字符串没有相同的字符串那就直接返回其长度即可,然后其他的字符串除了看是否有相同字符串之外还要判断其是否为比他长的字符串的子串。按照这个逻辑我们就可以写出下面的代码:

//45%
public int findLUSlength1(String[] strs) {
//首先按照字符串的长度进行降序排列
Arrays.sort(strs, new Comparator<String>() {
public int compare(String o1, String o2) {
return o2.length() - o1.length();
}
});

//获得包含相同字符串的元素,保存在set中
Set<String> duplicates = getDuplicates(strs);
//由长到短遍历字符串,对于包含相同字符串的元素则直接放弃判断
for(int i = 0; i < strs.length; i++) {
if(!duplicates.contains(strs[i])) {
//如果最长的字符串满足,则直接返回即可
if(i == 0) return strs[0].length();
//否则的话,要判断其是否为比他长的字符串的子串,如果不是则返回其长度
for(int j = 0; j < i; j++) {
if(isSubsequence(strs[j], strs[i])) break;
if(j == i-1) return strs[i].length();
}
}
}
return -1;
}

public boolean isSubsequence(String a, String b) {
int i = 0, j = 0;
while(i < a.length() && j < b.length()) {
if(a.charAt(i) == b.charAt(j)) j++;
i++;
}
return j == b.length();
}

private Set<String> getDuplicates(String[] strs) {
Set<String> set = new HashSet<String>();
Set<String> duplicates = new HashSet<String>();
for(String s : strs) {
if(set.contains(s)) duplicates.add(s);
set.add(s);
}
return duplicates;
}


此外,我们可以在排序的时候不仅仅按照字符串长度还参考字符串本身比较结果,这样相等的字符串就会相邻,我们就可以省去使用Set来获取相等字符串的步骤从而提升代码效率。如下所示:

//68%
public int findLUSlength(String[] strs) {
Arrays.sort(strs, new Comparator<String>() {
public int compare(String a, String b) {
return a.length() != b.length() ? a.length() - b.length() : a.compareTo(b);
}
});

for(int i = strs.length - 1; i >= 0; i--) {
if(i > 0 && !strs[i].equals(strs[i - 1]) || i == 0) {
int j = i + 1;
for(; j < strs.length; j++)
if(isSubSequence(strs[i], strs[j]))
break;
if(j == strs.length)
return strs[i].length();
}
}

return -1;
}

private boolean isSubSequence(String a, String b) {
if(a.equals(b)) return true;
int p = 0;
for(int i = 0; i < b.length() && p < a.length(); i++)
if(b.charAt(i) == a.charAt(p))
p++;
return p == a.length();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: