447. Number of Boomerangs\187. Repeated DNA Sequences\537. Complex Number Multiplication

447. Number of Boomerangs

DESCRIPTION

Given n points in the plane that are all pairwise distinct, a “boomerang” is a tuple of points (i, j, k) such that the distance between i and j equals the distance between i and k (the order of the tuple matters).

Find the number of boomerangs. You may assume that n will be at most 500 and coordinates of points are all in the range [-10000, 10000] (inclusive).

Example:

Input:
[[0,0],[1,0],[2,0]]

Output:
2

Explanation:
The two boomerangs are [[1,0],[0,0],[2,0]] and [[1,0],[2,0],[0,0]]

This problem is very easy.

From the problem we know that if we can calculate every number’s same distance set, than we sum than up with arrangement method to get result.

The whole algorithm shows below:

1 go through every element in vector
1.1 calculate the distance between this element with other elements in the vector with hash map.
1.2 calculate arrangement result A2n with hash map to result
1.3 clear hash map
2 return result

IMPLEMENTATION

class Solution {
public:
    int numberOfBoomerangs(vector<pair<int, int>>& points) {
        map<int, int> dis;
        int res = 0, num_point = points.size();

        for(int ind1 = 0; ind1 < num_point; ind1++) {
            for(int ind2 = 0; ind2 < num_point; ind2++) {
                int dis_tmp = (points[ind1].first - points[ind2].first)* (points[ind1].first - points[ind2].first) + (points[ind1].second - points[ind2].second)*(points[ind1].second - points[ind2].second);
                dis[dis_tmp]++;
            }
            map<int, int>::iterator  it;
            for(it = dis.begin(); it != dis.end(); it++) 
                if(it->first != 0)
                    res += (it->second)*(it->second - 1);
            dis.erase(dis.begin(), dis.end());    
        }


        return res;
    }
};

187. Repeated DNA Sequences

DESCRIPTION

All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: “ACGAATTCCG”. When studying DNA, it is sometimes useful to identify repeated sequences within the DNA.

Write a function to find all the 10-letter-long sequences (substrings) that occur more than once in a DNA molecule.

For example,


Given s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT",

Return:
["AAAAACCCCC", "CCCCCAAAAA"].

IMPLEMENTATION

the first method I write will meet with TLE, I use a map:

element_hash( hash for per 10 chars) -> vector< int > (vector contains the index of the same hash)

if there exists duplicate, I would push it into result.

class Solution {
public:
    vector<string> findRepeatedDnaSequences(string s) {
        set<string> res;
        map<vector<int>, vector<int>> hash;
        int len = s.length();
        vector<int> ele_hash(4, 0);

        for(int i = 0; i <= len - 10; i++) {
            if(!i) {
                for(int j = i; j < i + 10; j++) {
                    if(s[j] == 'A') ele_hash[0]++;
                    else if(s[j] == 'C') ele_hash[1]++;
                    else if(s[j] == 'G') ele_hash[2]++;
                    else if(s[j] == 'T') ele_hash[3]++;
                }
            }    
            else {
                if(s[i-1] == 'A') ele_hash[0]--;
                else if(s[i-1] == 'C') ele_hash[1]--;
                else if(s[i-1] == 'G') ele_hash[2]--;
                else if(s[i-1] == 'T') ele_hash[3]--;
                if(s[i+9] == 'A') ele_hash[0]++;
                else if(s[i+9] == 'C') ele_hash[1]++;
                else if(s[i+9] == 'G') ele_hash[2]++;
                else if(s[i+9] == 'T') ele_hash[3]++;
            }    
            if(hash.count(ele_hash) > 0) {
                vector<int> &tar_ele = hash[ele_hash];
                bool isFind = false;
                for(vector<int>::iterator it = tar_ele.begin(); it != tar_ele.end(); it++) { 
                    if(s.substr(*it, 10) == s.substr(i, 10))  {
                        res.insert(s.substr(i, 10));
                        isFind = true;
                        break;
                    }    
                }  
                if(!isFind)
                    tar_ele.push_back(i);
            }
            else {
                vector<int> tmp;
                tmp.push_back(i);
                hash[ele_hash] = tmp;
            }
        }
        return vector<string>(res.begin(), res.end());
    }
};

method 2: prefix tree

another method to deal with TLE, I find here the compared string with constant length 10.

So it is easy to deal with this problem with trie tree.

The whole algorithm shows below:

1 go through every ten-char string element in string s
1.1 go through the substring and judge if there exists node for current string.
If not, create the node until to the last char. If in the end there is not empty, this string is created by previous node, but we don’ t know how much has visited.
1.2 So I set the existing last node with isFind. When the second visited, it will be set to true. So the third, fourth, fifth and above will not push into result vector.
2 return the resulted string vector.

class TrieNode {
    public:
        TrieNode* next[4];
        bool isFind = false;
        TrieNode():isFind(false) {
            for(int i = 0; i < 4; i++)
                next[i] = NULL;
        } 
};

class Solution {
public:
    vector<string> findRepeatedDnaSequences(string s) {
        int len = s.length();
        vector<string> res;
        TrieNode* root = new TrieNode();
        TrieNode* cur = NULL;
        for(int i = 0; i <= len - 10; i++) {
            cur = root;
            for(int j = i; j < i+10; j++) {
                if(s[j] == 'A') {
                    if(cur->next[0]) { 
                        if(j == i+9 && !cur->next[0]->isFind) {
                            res.push_back(s.substr(i, 10));
                            cur->next[0]->isFind = true;
                        }    
                    }
                    else 
                        cur->next[0] = new TrieNode();
                    cur = cur->next[0];
                }
                else if(s[j] == 'C') {
                    if(cur->next[1]) { 
                        if(j == i+9 && !cur->next[1]->isFind) {
                            res.push_back(s.substr(i, 10));
                            cur->next[1]->isFind = true;
                        }    
                    }
                    else
                        cur->next[1] = new TrieNode();
                    cur = cur->next[1];
                }
                else if(s[j] == 'G') {
                    if(cur->next[2]) { 
                        if(j == i+9 && !cur->next[2]->isFind) {
                            res.push_back(s.substr(i, 10));
                            cur->next[2]->isFind = true;
                        }    
                    }
                    else 
                        cur->next[2] = new TrieNode();
                    cur = cur->next[2];
                }
                else {
                    if(cur->next[3]) { 
                        if(j == i+9 && !cur->next[3]->isFind) {
                            res.push_back(s.substr(i, 10));
                            cur->next[3]->isFind = true;
                        }    
                    }
                    else 
                        cur->next[3] = new TrieNode();
                    cur = cur->next[3];
                }
            }
        }
        return res;
    }
};

By the way, the code is too redundant, I utilize a map to map char to index to essentialize the code.

class TrieNode {
    public:
        TrieNode* next[4];
        bool isFind = false;
        TrieNode():isFind(false) {
            memset(this->next, 0, 4*sizeof(TrieNode*));
        } 
};

class Solution {
public:
    vector<string> findRepeatedDnaSequences(string s) {
        int len = s.length();
        vector<string> res;
        map<char, int> mp;
        mp['A'] = 0, mp['C'] = 1, mp['G'] = 2, mp['T'] = 3;
        TrieNode* root = new TrieNode();
        TrieNode* cur = NULL;
        for(int i = 0; i <= len - 10; i++) {
            cur = root;
            for(int j = i; j < i+10; j++) {
                int ind = mp[s[j]];
                if(cur->next[ind]) { 
                    if(j == i+9 && !cur->next[ind]->isFind) {
                        res.push_back(s.substr(i, 10));
                        cur->next[ind]->isFind = true;
                    }    
                }
                else 
                    cur->next[ind] = new TrieNode();
                cur = cur->next[ind];
            }
        }
        return res;
    }
};

537. Complex Number Multiplication

DESCRIPTION

Given two strings representing two complex numbers.

You need to return a string representing their multiplication. Note i2 = -1 according to the definition.

Example 1:

Input: "1+1i", "1+1i"
Output: "0+2i"
Explanation: (1 + i) * (1 + i) = 1 + i2 + 2 * i = 2i, and you need convert it to the form of 0+2i.
Example 2:
Input: "1+-1i", "1+-1i"
Output: "0+-2i"
Explanation: (1 - i) * (1 - i) = 1 + i2 - 2 * i = -2i, and you need convert it to the form of 0+-2i.

Note:

The input strings will not have extra blank.
The input strings will be given in the form of a+bi, where the integer a and b will both belong to the range of [-100, 100]. And the output should be also in this form.

As we know, (a +b i)(c + d i) = ac - db + (ad + bc) i

So the task is to extract number a, b, c, d then use the principal to get final result.

IMPLEMENTATION

class Solution {
public:
    string complexNumberMultiply(string a, string b) {
        int lena = a.size(), lenb = b.size();
        pair<int, int> complex[2];
        bool neg = false, fst = true;
        complex[0].first = 0, complex[0].second = 0;
        for(int i = 0; i < lena; i++) {
            if(a[i] == '-') { neg = true; cout << "negative detected" << endl;}
            else if(isdigit(a[i])) {
                if(fst)   complex[0].first = complex[0].first*10 + a[i] - '0';
                else complex[0].second = complex[0].second*10 + a[i] - '0';
                if(i == lena - 2) complex[0].second = neg? -1*complex[0].second:complex[0].second;
            }
            else if(a[i] == '+') {
                complex[0].first = neg? -1*complex[0].first:complex[0].first;
                neg = false;
                fst = false;
            }
        }
        neg = false, fst = true;
        complex[1].first = 0, complex[1].second = 0;
        for(int i = 0; i < lenb; i++) {
            if(b[i] == '-') neg = true;
            else if(isdigit(b[i])) {
                if(fst)   complex[1].first = complex[1].first*10 + b[i] - '0';
                else complex[1].second = complex[1].second*10 + b[i] - '0';
                if(i == lenb - 2) complex[1].second = neg? -1*complex[1].second:complex[1].second;
            }
            else if(b[i] == '+') {
                complex[1].first = neg? -1*complex[1].first:complex[1].first;
                neg = false;
                fst = false;
            }
        }
        cout << complex[0].first << " " << complex[0].second << endl;
        cout << complex[1].first << " " << complex[1].second << endl;
        int part_real = complex[1].first*complex[0].first - complex[1].second*complex[0].second;
        int part_comp = complex[1].first*complex[0].second + complex[1].second*complex[0].first;
        return to_string(part_real) + '+' + to_string(part_comp) + 'i';
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值