137. Single Number II\393. UTF-8 Validation\547. Friend Circles

来源:互联网 发布:杭州运维前哨网络骗局 编辑:程序博客网 时间:2024/05/15 17:06

  • Single Number II
    • DESCRIPTION
    • IMPLEMENTATION
  • UTF-8 Validation
    • DESCRIPTION
    • IMPLEMENTATION
  • Friend Circles
    • DESCRIPTION
    • IMPLEMENTATION

137. Single Number II

DESCRIPTION

Given an array of integers, every element appears three times except for one, which appears exactly once. Find that single one.

Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

Here I find the real difference between three times number and once number is the times appear for every digit. If there is no once element, then appearance of every digit 1 is times of 3. But with once element, there exists redundant digits.

IMPLEMENTATION

class Solution {public:    int singleNumber(vector<int>& nums) {        int len = nums.size();        int res = 0;        if(!len) return res;        vector<int> rec(32, 0);        for(auto ele:nums) {            for(int idx = 0; idx < 32; idx++)                rec[idx] += (ele & (1 << idx)) != 0;        }        for(int idx = 0; idx < 32; idx++)             if(rec[idx]%3)                 res |= (1 << idx);        return res;            }};

393. UTF-8 Validation

DESCRIPTION

A character in UTF8 can be from 1 to 4 bytes long, subjected to the following rules:

For 1-byte character, the first bit is a 0, followed by its unicode code.
For n-bytes character, the first n-bits are all one’s, the n+1 bit is 0, followed by n-1 bytes with most significant 2 bits being 10.
This is how the UTF-8 encoding would work:

   Char. number range  |        UTF-8 octet sequence      (hexadecimal)    |              (binary)   --------------------+---------------------------------------------   0000 0000-0000 007F | 0xxxxxxx   0000 0080-0000 07FF | 110xxxxx 10xxxxxx   0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx   0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxxGiven an array of integers representing the data, return whether it is a valid utf-8 encoding.Note:The input is an array of integers. Only the least significant 8 bits of each integer is used to store the data. This means each integer represents only 1 byte of data.

Example 1:

data = [197, 130, 1], which represents the octet sequence: 11000101 10000010 00000001.Return true.It is a valid utf-8 encoding for a 2-bytes character followed by a 1-byte character.Example 2:data = [235, 140, 4], which represented the octet sequence: 11101011 10001100 00000100.Return false.The first 3 bits are all one's and the 4th bit is 0 means it is a 3-bytes character.The next byte is a continuation byte which starts with 10 and that's correct.But the second continuation byte does not start with 10, so it is invalid.

From above description, we know that the input is a vector and which element in the vector is regarded as one decoded byte in UTF-8 number.

So my algorithm shows below:

1 go through the whole vector
1.1 get the first byte of the UTF-8 decoded number and calculate the sequential 1s in the first byte.
1.2 if the num_byte is less than 0 or larger than 4 or larger than 256 or smaller than 0 , return false; otherwise, go through num elements in the vector.
1.3 verify the num elements is satisfied with the condition or not. If not, return false; otherwise continue to go.
2 return true.

IMPLEMENTATION

My code shows below with computation complexity O(n2), and the space complexity is O(1)

class Solution {public:    bool validUtf8(vector<int>& data) {        int num = data.size();        if(num <= 0) return false;        int num_byte = 0;        for(int idx = 0; idx < num;) {            int fst_byte = data[idx];            num_byte = 0;            if(fst_byte > 256 || fst_byte < 0) return false;             for(int idx = 7; idx >= 0; idx--) {                 if((fst_byte & (1 << idx))!=0)                    num_byte++;                else                     break;            }               if(!num_byte) {                idx++;                continue;            }            else if(num_byte == 1 || num_byte > 4) return false;            cout << num_byte << endl;                    int idx_tail = idx + num_byte;            if(idx_tail > num) return false;            for(idx = idx + 1; idx < idx_tail; idx++)                if(data[idx] > 256 || data[idx] < 0 || ((data[idx] >> 6) != 2))                    return false;        }                return true;        }};

I change the code to a more concise version according to [1]

class Solution {public:    bool validUtf8(vector<int>& data) {        int num = data.size();        if(num <= 0) return false;        int cnt = 0;        for(auto ele:data) {            if(!cnt) {                if(!(ele >> 7))   continue;                else if((ele >> 5) == 0b110) cnt = 1;                else if((ele >> 4) == 0b1110) cnt = 2;                else if((ele >> 3) == 0b11110) cnt = 3;                else return false;            }            else {                if((ele >> 6) != 0b10) return false;                cnt--;            }        }        return !cnt;        }};

547. Friend Circles

DESCRIPTION

There are N students in a class. Some of them are friends, while some are not. Their friendship is transitive in nature. For example, if A is a direct friend of B, and B is a direct friend of C, then A is an indirect friend of C. And we defined a friend circle is a group of students who are direct or indirect friends.

Given a N*N matrix M representing the friend relationship between students in the class. If M[i][j] = 1, then the ith and jth students are direct friends with each other, otherwise not. And you have to output the total number of friend circles among all the students.

Example 1:Input: [[1,1,0], [1,1,0], [0,0,1]]Output: 2Explanation:The 0th and 1st students are direct friends, so they are in a friend circle. The 2nd student himself is in a friend circle. So return 2.
Example 2:Input: [[1,1,0], [1,1,1], [0,1,1]]Output: 1Explanation:The 0th and 1st students are direct friends, the 1st and 2nd students are direct friends, so the 0th and 2nd students are indirect friends. All of them are in the same friend circle, so return 1.Note:N is in range [1,200].M[i][i] = 1 for all students.If M[i][j] = 1, then M[j][i] = 1.

IMPLEMENTATION

This problem is described as below:

We visit every node in the matrix and do BFS in the node which is not visited before.

So the whole algorithm can be written as:

1 go through the node in the vector which is not visited before
1.1 push the nearest visited node into queue.
1.2 pop the top from queue and and visited its friends until the queue is empty.
1.3 add increament to result.
2 return num_circle

The code shown below:

class Solution {public:    int isVisitedAll(vector<bool> & waiting, int dim) {        for(int idx = 0; idx < dim; idx++)            if(!waiting[idx]) {                waiting[idx] = true;                return idx;            }            return dim;            }    int findCircleNum(vector<vector<int>>& M) {        int num_circle = 0;        int dim = M.size();        vector<bool> waiting_list(dim, false);        int next_mem = 0;        while((next_mem = isVisitedAll(waiting_list, dim)) != dim) {            queue<int> cur_que;            cur_que.push(next_mem);            while(!cur_que.empty()) {                int tp = cur_que.front();                cur_que.pop();                M[tp][tp] = 0;                for(int idx = 0; idx < dim; idx++) {                    if(M[tp][idx] && !waiting_list[idx]) {                        cur_que.push(idx);                        waiting_list[idx] = true;                    }                    }            }            num_circle++;        }            return num_circle;    }};

Ref Link:
[1] UTF-8 Validation: https://discuss.leetcode.com/topic/57195/concise-c-implementation/2

1 0
原创粉丝点击