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

来源:互联网 发布:美工主要负责什么 编辑:程序博客网 时间:2024/04/29 13:02

  • Number of Boomerangs
    • DESCRIPTION
    • IMPLEMENTATION
  • Repeated DNA Sequences
    • DESCRIPTION
    • IMPLEMENTATION
  • Complex Number Multiplication
    • DESCRIPTION
    • IMPLEMENTATION

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:2Explanation: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';    }};
0 0