zoukankan      html  css  js  c++  java
  • 好!maximum-product-of-word-lengths

    以后看到个数比较少,性能比较高,就要第一时间想到位操作!

    这道题目mock没有通过。超时了。。。。。。

    原来题目解法的思路非常非常好!

    开始我关注于降低n*n的复杂度,但是这道题目复杂度高在每个字符串长,所以一定要问清楚题目

    新做的记录:
    package com.company;
    
    
    import java.util.*;
    import java.util.List;
    
    
    class Solution {
        public int maxProduct(String[] words) {
            // int是32位,足够处理了。真的很牛逼
            // 以后看到个数比较少,性能比较高,就要第一时间想到位操作!
            // 开始我关注于降低n*n的复杂度,但是这道题目复杂度高在每个字符串长,所以一定要问清楚题目
            List<Integer> ilist = new ArrayList<>();
            for (int i=0; i<words.length; i++) {
                int nb = 0;
                for (int j=0; j<words[i].length(); j++) {
                    nb |= 1 << (words[i].charAt(j) - 'a');
                }
                ilist.add(nb);
            }
            int ret = 0;
            for (int i=0; i<words.length; i++) {
                for (int j=i+1; j<words.length; j++) {
                    if ((ilist.get(i) & ilist.get(j)) == 0) {
                        if (words[i].length() * words[j].length() > ret) {
                            ret = words[i].length() * words[j].length();
                        }
                    }
                }
            }
            return ret;
        }
    }
    
    public class Main {
    
        public static void main(String[] args) {
            // write your code here
            System.out.println("Hello");
            Solution solution = new Solution();
    
            String[] words= {"cdea","bdd"};
            int ret = solution.maxProduct(words);
            System.out.printf("Get ret: %d
    ", ret);
    
        }
    }

    原来做过的记录

    https://leetcode.com/problems/maximum-product-of-word-lengths/
    
    // 我在尽量做到比n*n效率更高
    // 对比new solution和previous solution
    // new solution 是纯n*n,优化在字符串比较
    // 对于大数据,耗时0ms
    // previous solution理论上比n*n要快,
    // 但是因为涉及vector的频繁增删、复制
    // 实际要慢的多,对于大数据耗时800+ms
    
    // 总的来看,stl container的复制、删除等,耗时很大
    
    class Solution {
        vector<pair<int, int>> vec;
        vector<string> words;
        int **DP;
        // 比较的好方法
        int *bits;
        
        static bool my_compair(const string &a, const string &b) {
            if (a.size() > b.size()) {
                return true;
            }
            else {
                return false;
            }
        }
        
        void insert(int i, int j) {
            int f = words[i].size() * words[j].size();
            
            int vlen = vec.size();
            int begin = 0;
            int end = vlen - 1;
            
            int mid;
            int tmp;
            while (begin <= end) {
                mid = (begin + end) / 2;
                tmp = words[vec[mid].first].size() * words[vec[mid].second].size();
                
                if (f == tmp) {
                    begin = mid + 1;
                    break;
                }
                else if (f > tmp) {
                    end = mid - 1;
                }
                else {
                    begin = mid + 1;
                }
            }
            vec.insert(vec.begin()+begin, make_pair(i, j));
        }
        
        int valid(int i, int j) {
            if ((bits[i] & bits[j]) != 0) {
                return 0;
            }
            return words[i].size() * words[j].size();
        }
        
    public:
        int maxProduct(vector<string>& w) {
            words = w;
            
            int wlen = words.size();
            if (wlen == 0) {
                return 0;
            }
            sort(words.begin(), words.end(), my_compair);
            
            // 初始化bits
            bits = new int[wlen];
            memset(bits, 0, sizeof(int)*wlen);
            for (int i=0; i<wlen; i++) {
                string wstr = words[i];
                int slen = wstr.size();
                for (int j=0; j<slen; j++) {
                    bits[i] |= 1 << (wstr[j]-'a');
                }
            }
            
            // new solution(0 ms for big test case)
            int result = 0;
            for (int i=0; i<wlen-1; i++) {
                for (int j=i+1; j<wlen; j++) {
                    if ((bits[i]&bits[j]) == 0) {
                        int tmp = words[i].size() * words[j].size();
                        if (tmp > result) {
                            result = tmp;
                        }
                    }
                }
            }
            return result;
            
            // previous solution (800ms for big test case)
            DP = new int*[wlen];
            for (int i=0; i<wlen; i++) {
                DP[i] = new int[wlen];
                // 注意,new出来的数据初始值,不一定为0
                memset(DP[i], 0, sizeof(int)*wlen);
            }
            
            // 根据相乘的长度排序
            vec.push_back(make_pair(0, 1));
            DP[0][1] = 1;
            
            int fir;
            int sec;
            int tmp;
            
            while (!vec.empty()) {
                fir = vec[0].first;
                sec = vec[0].second;
                vec.erase(vec.begin());
                
                tmp = valid(fir, sec);
                if (tmp > result) {
                    result = tmp;
                }
                
                if (fir + 1 < sec && DP[fir+1][sec] == 0 &&
                    words[fir+1].size() * words[sec].size() > result) {
                    insert(fir+1, sec);
                    DP[fir+1][sec] = 1;
                }
                if (sec + 1 < wlen && DP[fir][sec+1] == 0 &&
                    words[fir].size() * words[sec+1].size() > result) {
                    insert(fir, sec+1);
                    DP[fir][sec+1] = 1;
                }
            }
            return result;
        }
    };
    
    
    // 下面是我在 Mock里面做的,超时了。重来。
    package com.company;
    
    
    import java.awt.*;
    import java.util.*;
    import java.util.List;
    
    
    class Solution {
        public int maxProduct(String[] words) {
            // 直接用n*n*size的方法肯定不好
            // 注意限制条件, lower case的字符
    
            Map<Integer, Set<Integer>> mp = new HashMap<>();
    
            List<Integer> clist = new ArrayList<>();
    
            for (int i=0; i<words.length; i++) {
                clist.add(i);
    
                // 过滤
                char[] chs = words[i].toCharArray();
                Set<Integer> wSet = new HashSet();
                for (char ch :chs) {
                    wSet.add(ch - 'a');
                }
                Iterator<Integer> iter = wSet.iterator();
                while (iter.hasNext()) {
                    int key = iter.next();
                    if (!mp.containsKey(key)) {
                        Set<Integer> st = new HashSet<>();
                        st.add(i);
                        mp.put(key, st);
                    }
                    else {
                        Set<Integer> st = mp.get(key);
                        st.add(i);
                        mp.put(key, st);
                    }
                }
    
            }
    
            int ret = 0;
            for (int i=0; i<words.length; i++) {
                Set<Integer> oSet = new HashSet<>(clist);
                char[] chs = words[i].toCharArray();
                Set<Integer> wSet = new HashSet();
                for (char ch :chs) {
                    wSet.add(ch - 'a');
                }
                Iterator<Integer> iter = wSet.iterator();
                while (iter.hasNext()) {
                    int key = iter.next();
                    Set<Integer> st = mp.get(key);
                    oSet.removeAll(st);
                }
                iter = oSet.iterator();
                while (iter.hasNext()) {
                    int index = iter.next();
                    if (words[i].length() * words[index].length() > ret) {
                        ret = words[i].length() * words[index].length();
                    }
                }
            }
            return ret;
    
        }
    }
    
    public class Main {
    
        public static void main(String[] args) {
            // write your code here
            System.out.println("Hello");
            Solution solution = new Solution();
    
            String[] words= {};
            int ret = solution.maxProduct(words);
            System.out.printf("Get ret: %d
    ", ret);
    
        }
    }
  • 相关阅读:
    bzoj4543 长链剖分
    tarjan算法
    uoj36 玛里苟斯 高斯消元做法
    狄利克雷卷积
    斜率优化
    将一个工作簿拆分为多个工作表
    如何制作Excel斜线表头
    逻辑函数(IF函数)
    逻辑函数(AND,OR,NOT)
    Excel中提取英文,数值和编码(LEN函数)
  • 原文地址:https://www.cnblogs.com/charlesblc/p/5989796.html
Copyright © 2011-2022 走看看