LeetCode上做题之体会(五)

1、求两个数组的元素交集

Intersection of Two Arrays
Given two arrays, write a function to compute their intersection.
Example:
Given nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [2].
Note:
Each element in the result must be unique.
The result can be in any order.

这道题其实很简单,因为没有限制什么条件,我一开始就用最直接的方法来搞定他。下面看代码:

        int[] r = new int[nums1.length];
        HashSet<Integer> hs = new HashSet<>();
        int c = 0;
        for(int i = 0; i < nums1.length; i++){
            for(int j = 0; j < nums2.length; j++){
                if(nums1[i] == nums2[j] && hs.add(nums1[i]) == true){
                    r[c++] = nums1[i];
                    break;
                }
            }
        }
        int[] result = new int[c];
        int flag = 0;
        for(int i = 0; i < c; i++){
            if(r[i] == 0){
                if(hs.contains(r[i]) == false){
                    break;
                }
                else{
                    if(flag < 1){
                        flag++;
                        result[i] = r[i];
                    }
                    else{
                        break;
                    }
                }
            }
            else
                result[i] = r[i];
        }
        return result;

显然这种方法不是最快的,我还想到一种是需要借助到HashSet来解题的,下面请看代码:

        HashSet<Integer> set = new HashSet<>();
        HashSet<Integer> inter = new HashSet<>();
        for(int i = 0 ; i < nums1.length ; i++)
            set.add(nums1[i]);
        for(int i = 0 ; i < nums2.length ; i++){
            if(set.contains(nums2[i]))
                inter.add(nums2[i]); // only add unique elements common to both
        }
        int[] result = new int[inter.size()];
        int count = 0;
        for(Integer in : inter)
            result[count++] = in;

        return result;

之后,又在讨论区看到有用一行代码解决的,里面是用Java8的lambda表达式来完成的:

return Arrays.stream(nums1).distinct().filter(p->{return Arrays.stream(nums2).anyMatch(q->{return q==p;});}).toArray();
要是大家没有了解过lambda表达式的话是看不懂这道代码到底在写什么的。

这里友情提示一下,有兴趣了解的话给大家提供一个链接,大家可以点过去看看:
Java8之lambda表达式

这代码建议大家看看就好,在实际开发里面不要滥用,这行代码虽然简单,但是里面的时间复杂度是很大的。

2、求交集II

Intersection of Two Arrays II
Given two arrays, write a function to compute their intersection.
Example:
 Given nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [2, 2].
Note:
 Each element in the result should appear as many times as it shows in both arrays.
 The result can be in any order.
Follow up:
  What if the given array is already sorted? How would you optimize your algorithm?
  What if nums1’s size is small compared to num2’s size? Which algorithm is better?
  What if elements of nums2 are stored on disk, and the memory is limited such that you cannot load all elements into the memory at once?

这是上面那一道题的变形而已,上题元素是唯一的,但是这个道题元素要求有多少对,都必须出现。这就要复杂一点,一开始试了几次,都没有调试好,错了好几次。好吧下面贴下我通过的代码:

        List<Integer> l = new ArrayList<>();
        int[] r = new int[nums1.length < nums2.length ? nums1.length : nums2.length];
        int num = 0;
        if(nums1.length > nums2.length){
            for(int i = 0; i < nums1.length; i++){
                l.add(nums1[i]);
            }
            for(int i = 0; i < nums2.length; i++){
                if(l.contains(nums2[i]) == true){
                    l.remove(l.indexOf(nums2[i]));
                    r[num++] = nums2[i];
                }
            }
        }
        else{
            for(int i = 0; i < nums2.length; i++){
                l.add(nums2[i]);
            }
            for(int i = 0; i < nums1.length; i++){
                if(l.contains(nums1[i]) == true){
                    l.remove(l.indexOf(nums1[i]));
                    r[num++] = nums1[i];
                }
            }
        }
        int[] result = new int[num];
        for(int i = 0; i < num; i++){
            result[i] = r[i];
        }
        return result;

还有一种方法,是将两个数组都先排好序,之后再进行比较,这种方法对题目中第三条要求是比较符合的,我们在学排序的时候就知道有外排序和内排序之分,我们平时做的排序都是内排序,第三点要求好像意思就是要我们用外排序来做的:

        if(nums1.length==0||nums2.length==0)
            return new int[0];
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        int p1=0;
        int p2=0;
        List<Integer> res=new ArrayList<Integer>();
        while(p1<nums1.length && p2<nums2.length){
            if(nums1[p1]==nums2[p2]){
                res.add(nums1[p1]);
                p1++;
                p2++;
            }
            else if(nums1[p1]<nums2[p2])
                p1++;
            else 
                p2++;
        }
        int[] t=new int[res.size()];
        for(int i=0;i<res.size();i++)
            t[i]=res.get(i);

        return t;

我是用ArrayList来做的,看到讨论区有用HashMap来做的,其实就是将元素所在的位置做了一下记录而已,代码在下面:

        HashMap<Integer, Integer> s = new HashMap<>();
        List<Integer> l = new ArrayList<Integer>();
        for (int i:nums1) 
            if (!s.containsKey(i)) s.put(i,1);
            else s.put(i,s.get(i)+1);
        for (int i:nums2) if(s.containsKey(i) && s.get(i) > 0) {
            l.add(i);
            s.put(i,s.get(i)-1);
        }
        int[] result = new int[l.size()];
        for (int i = 0; i < l.size();i++) {
            result[i] = l.get(i);  
        }
        return result;

3、同构字符串

Isomorphic Strings
Given two strings s and t, determine if they are isomorphic.
Two strings are isomorphic if the characters in s can be replaced to get t.
All occurrences of a character must be replaced with another character while preserving the order of characters. No two characters may map to the same character but a character may map to itself.
For example,
Given “egg”, “add”, return true.
Given “foo”, “bar”, return false.
Given “paper”, “title”, return true.
Note:
You may assume both s and t have the same length.

这道题目一上来,我很容易就想到了要用HashMap来解决,同构的话就是每个重复出现的字母要对应上,这样确实一下就能想到用映射来解决。其实用API中的HashMap来做的话时间会比较慢一点,可以自己构造一个简单的Hash映射关系数组来解决这个问题,下面我贴出了两种代码,看看吧:

public boolean isIsomorphic(String s, String t) {
        if(s == null || s.length() <= 1) return true;
        HashMap<Character,Character> map = new HashMap<>();
        for(int i = 0; i < s.length(); i++){
            if(map.containsKey(s.charAt(i))){
                if(map.get(s.charAt(i)).equals(t.charAt(i))){
                    continue;
                }
                else{
                    return false;
                }
            }
            else{
                if(!map.containsValue(t.charAt(i))){
                    map.put(s.charAt(i),t.charAt(i));
                }
                else{
                    return false;
                }
            }
        }
        return true;
    }
public boolean isIsomorphic(String s, String t) {
        int[] m = new int[512];
        for (int i = 0; i < s.length(); i++) {
            if (m[s.charAt(i)] != m[t.charAt(i)+256]) return false;
            m[s.charAt(i)] = m[t.charAt(i)+256] = i+1;
        }
        return true;
    }
第二种自己构造Hash映射的方法确实快了一点。
        char[] s1 = s.toCharArray();
        char[] t1 = t.toCharArray();
        int length = s1.length;
        if(length != t1.length) return false;
        char[] sm = new char[256];
        char[] tm = new char[256];
        for(int i=0; i<length; i++){
            char sc = s1[i];
            char tc = t1[i];
            if(sm[sc] == 0 && tm[tc] == 0){
                sm[sc] = tc;
                tm[tc] = sc;
            }else{
                if(sm[sc] != tc || tm[tc] != sc){
                    return false;
                }
            }
        }
        return true;

最后在讨论区看到一个3msAC的,其实方法和上面第二种差不多,但是为什么会快那么多呢?

5、词模式匹配

Word Pattern
Given a pattern and a string str, find if str follows the same pattern.
Here follow means a full match, such that there is a bijection between a letter in pattern and a non-empty word in str.
Examples:
pattern = “abba”, str = “dog cat cat dog” should return true.
pattern = “abba”, str = “dog cat cat fish” should return false.
pattern = “aaaa”, str = “dog cat cat dog” should return false.
pattern = “abba”, str = “dog dog dog dog” should return false.
Notes:
You may assume pattern contains only lowercase letters, and str contains lowercase letters separated by a single space.

前几个星期在无意中发现另外一个刷题网站,外国的,可以装X,下个给个网址吧,CodeWars。这个网站要注册时还要解决几个问题,我选的是Java语言,所以只需要做两道题。其他语言就不确定了。以后在这个网站遇到有趣的题目可能会写另外的一个专题,有兴趣的到时候可以关注一下哦。

——————————————— 分割线 —————————————————–

以上内容编辑于 2016年05月07日 22:28:15 ,由于放在草稿箱太久,现在把重新出来发布。

猜你喜欢

转载自blog.csdn.net/u014306011/article/details/51340483