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

本文介绍了三个经典算法问题的解决方案:找出数组中仅出现一次的数字、验证UTF-8编码的有效性以及计算社交圈的数量。通过详细解析算法思路与实现代码,为读者提供了深入理解这些问题的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 10xxxxxx
Given 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: 2
Explanation: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: 1
Explanation: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

资源下载链接为: https://pan.quark.cn/s/9648a1f24758 这个HTML文件是一个专门设计的网页,适合在告白或纪念日这样的特殊时刻送给女朋友,给她带来惊喜。它通过HTML技术,将普通文字转化为富有情感和创意的表达方式,让数字媒体也能传递深情。HTML(HyperText Markup Language)是构建网页的基础语言,通过标签描述网页结构和内容,让浏览器正确展示页面。在这个特效网页中,开发者可能使用了HTML5的新特性,比如音频、视频、Canvas画布或WebGL图形,来提升视觉效果和交互体验。 原本这个文件可能是基于ASP.NET技术构建的,其扩展名是“.aspx”。ASP.NET是微软开发的一个服务器端Web应用程序框架,支持多种编程语言(如C#或VB.NET)来编写动态网页。但为了在本地直接运行,不依赖服务器,开发者将其转换为纯静态的HTML格式,只需浏览器即可打开查看。 在使用这个HTML特效页时,建议使用Internet Explorer(IE)浏览器,因为一些老的或特定的网页特效可能只在IE上表现正常,尤其是那些依赖ActiveX控件或IE特有功能的页面。不过,由于IE逐渐被淘汰,现代网页可能不再对其进行优化,因此在其他现代浏览器上运行可能会出现问题。 压缩包内的文件“yangyisen0713-7561403-biaobai(html版本)_1598430618”是经过压缩的HTML文件,可能包含图片、CSS样式表和JavaScript脚本等资源。用户需要先解压,然后在浏览器中打开HTML文件,就能看到预设的告白或纪念日特效。 这个项目展示了HTML作为动态和互动内容载体的强大能力,也提醒我们,尽管技术在进步,但有时复古的方式(如使用IE浏览器)仍能唤起怀旧之情。在准备类似的个性化礼物时,掌握基本的HTML和网页制作技巧非常
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值