校招刷题记录

刷题记录

比特

Brian Kernighan算法

删除二进制比特最右侧1;

f(x)=x&(x-1);
例:
	    7=111
	    6=110
 f(7)=7&6=110

例:
		     52=110100
			 51=110011
	f(52)=52&51=110000

前 n 个数字二进制中 1 的个数

排序

快速排序

//快速排序
void quick_sort(int s[], int l, int r)
{
    
    
    if (l < r)
    {
    
    
        //Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1
        int i = l, j = r, x = s[l];
        while (i < j)
        {
    
    
            while(i < j && s[j] >= x) // 从右向左找第一个小于x的数
                j--;
            if(i < j)
                s[i++] = s[j];

            while(i < j && s[i] < x) // 从左向右找第一个大于等于x的数
                i++;
            if(i < j)
                s[j--] = s[i];
        }
        s[i] = x;
        quick_sort(s, l, i - 1); // 递归调用
        quick_sort(s, i + 1, r);
    }
}

例题:数组中的第k大的数字

class Solution {
    
    
public:
    int quick_sort(vector<int>& nums,int l, int r)
    {
    
    
        if(l<r)
        {
    
    
            int i=l,j=r,x=nums[l];
            while(i<j)
            {
    
    
                while(i<j&&nums[j]>=x)
                    j--;
                if(i<j)
                    nums[i++]=nums[j];
                while(i<j&&nums[i]<x)
                    i++;
                if(i<j)
                    nums[j--]=nums[i];
                nums[i]=x;
            }
            return i;
        }
        return l;
    }
    int findKthLargest(vector<int>& nums, int k) {
    
    
        int n=nums.size();
        int l=0,r=n-1;
        int target=n-k;
        int index=quick_sort(nums,l,r);
        while(index!=target)
        {
    
    
            if(index>target)
            {
    
    
                r=index-1;
            }
            else
            {
    
    
                l=index+1;
            }
            index=quick_sort(nums,l,r);
        }
        return nums[target];
    }
};

归并排序

//归并排序
void Merge(int arr[],int l,int mid,int r)
{
    
    
    int i=l,j=mid+1,k=0;
    int temp[r-l+1];
    while(i<=mid&&j<=r)
    {
    
    
        if(arr[i]<=arr[j])
            temp[k++]=arr[i++];
        else
            temp[k++]=arr[j++];
    }
    while(i<=mid)
        temp[k++]=arr[i++];
    while(j<=r)
        temp[k++]=arr[j++];
    for(i=l,k=0;i<=r;i++,k++)
        arr[i]=temp[k];
}
void MergeSort(int arr[],int l,int r)
{
    
    
    if(l<r)
    {
    
    
        int mid=(l+r)/2;
        MergeSort(arr,l,mid);
        MergeSort(arr,mid+1,r);
        Merge(arr,l,mid,r);
    }
}

广度优先搜索

三国鼎立

//C++
#include<iostream>
#include<string>
#include<vector>
using namespace std;
void dfs(vector<vector<int>> &area,int i,int j,int k)
{
    
    
    int n=area.size();
    int m=area[0].size();
    area[i][j]=0;
    if(i-1>=0&&area[i-1][j]==k)
        dfs(area,i-1,j,k);
    if(i+1<n&&area[i+1][j]==k)
        dfs(area,i+1,j,k);
    if(j-1>=0&&area[i][j-1]==k)
        dfs(area,i,j-1,k);
    if(j+1<m&&area[i][j+1]==k)
        dfs(area,i,j+1,k);
}
int main()
{
    
    
    int n,m;
    cin>>n>>m;
    vector<vector<int>> area(n,vector<int> (m));
    int count=0;
    for(int i=0;i<n;i++)
    {
    
    
        string s;
        cin>>s;
        for(int j=0;j<m;j++)
        {
    
    
            area[i][j]=s[j]-'0';
        }

    }
    for(int i=0;i<n;i++)
    {
    
    
        for(int j=0;j<m;j++)
        {
    
    
            if(area[i][j]!=0)
            {
    
    
                count++;
                dfs(area,i,j,area[i][j]);
            }
        }
    }
    cout<<count<<endl;
    return 0;
}

集合优先队列

集合操作

#include<set>
begin()    //返回set容器的第一个元素的地址
end()     //返回set容器的最后一个元素地址
clear()    //删除set容器中的所有的元素
empty()    //判断set容器是否为空
max_size()  //返回set容器可能包含的元素最大个数
size()    //返回当前set容器中的元素个数
erase(it)   //删除迭代器指针it处元素
insert(a)   //插入某个元素
count(a)    //统计元素a出现的次数,只有0/1,所以可以通过次函数返回判断某个元素是否在集合中
for(set<int>::iterator i=a.begin();i!=a.end();i++)   //迭代器

优先队列

#inclued<queue>
priority_queue <int> q; //默认大顶堆
//升序队列,小顶堆
priority_queue <int,vector<int>,greater<int> > q;

//降序队列,大顶堆
priority_queue <int,vector<int>,less<int> >q;
top()      //访问队头元素
empty()    //队列是否为空
size()     //返回队列内元素个数
push()     //插入元素到队尾 (并排序)
emplace()  //原地构造一个元素并插入队列
pop()      //弹出队头元素
swap()     //交换内容

狡猾的雇主

//使用两个集合解题
#include<iostream>
#include<vector>
#include<set>
#include<queue>
using namespace std;
int main()
{
    
    
    int n;
    cin>>n;
    vector<int> salary(n);
    priority_queue<int,vector<int>,greater<int> > q;
    set<int> a,b;
    for(int i=0;i<n;i++)
    {
    
    
        cin>>salary[i];
        if(a.count(salary[i])==1)
            b.insert(salary[i]);
        a.insert(salary[i]);
    }
    for(set<int>::iterator i=a.begin();i!=a.end();i++)
    {
    
    
        if(b.count(*i)==0)
            q.push(*i);
    }
    if(q.empty())
        cout<<-1<<endl;
    else{
    
    
        int c=q.top();
        cout<<c<<endl;
    }
    
    return 0;
}

并查集

初始化

//单独形成集合,每个节点的祖先为自己
int fa[size];
for(int i=0;i<size;i++)
	fa[i]=i;

查找

int findfather(int fa[], int x)
{
    
    
	if(fa[x]!=x)     //如果自己的祖先不是自己,说明不是集合的祖先
		fa[x]=findfather(fa,fa[x]);  //查找集合的祖先,并进行压缩
	return fa[x];
}

合并

bool unionn(int fa[],int i, int j)
    {
    
    
        int fa_i=findfa(fa,i);
        int fa_j=findfa(fa,j);
        if(fa_i!=fa_j)	
        {
    
    
            fa[fa_i]=fa_j;	//若两个节点祖先不同,不在同一个集合;则将其合并,其中一个祖先设为另一个的祖先,
            return true;     //刚建立集合,返回true
        }
        return false;   //之前就存在集合,返回false
    }

例题

剑指offer II 116 朋友圈

原题

def findfather(fa,i):
    if fa[i]!=i:
        fa[i]=findfather(fa,fa[i])
    return fa[i]
def union(fa,i,j):
    fa_i=findfather(fa,i)
    fa_j=findfather(fa,j)
    if fa_i!=fa_j:
        fa[i]=fa_j
        return True
    return False



if __name__=='__main__':
    n=int(input())
    M=[]
    for i in range(n):
        m=[int(j) for j in input().split(',')]
        M.append(m)

    fa=[-1]*n
    for i in range(n):
        fa[i]=i
    count=n
    for i in range(n):
        for j in range(i+1,n):
            if M[i][j]==1 and union(fa, i, j):
                count-=1
    print(count)

腾讯2021年校招 朋友圈

原题

#include<iostream>
using namespace std;

int findfa(int fa[],int x)
{
    
    
    if(fa[x]!=x)
        fa[x]=findfa(fa,fa[x]);
    return fa[x];
}
void unionn(int fa[],int x, int y)
{
    
    
    int fa_x=findfa(fa,x);
    int fa_y=findfa(fa,y);
    if(fa_x!=fa_y)
        fa[fa_x]=fa_y;

}

int main()
{
    
    
    int T;
    cin>>T;
    while(T--)
    {
    
    
        int fa[100001];
        int n;
        cin>>n;
        for(int i=0;i<100001;i++)
            fa[i]=i;
        while(n--)
        {
    
    
            int x,y;
            cin>>x>>y;
            unionn(fa,x,y);
        }
        vector<int> nums(100001);
        int max_len=0;
        for(int i=0;i<100001;i++)
        {
    
    
            int k=findfa(fa,i);
            nums[k]++;
            max_len=max(max_len,nums[k]);
        }
        cout<<max_len<<endl;
    }
    return 0;
}

剑指offer II 117 相似的字符串

原题

class Solution {
    
    
public:
    // 通过统计不同字符串的个数,判断是否相似
    bool similarity(string s1, string s2)
    {
    
    
        
        int diff=0;
        for(int i=0;i<s1.length();i++)
        {
    
    
            if(s1[i]!=s2[i])
                diff++;
        }
        if(diff<=2)
            return true;
        else
            return false;
    }
    //查找
    int findfateher(int fa[],int i)
    {
    
    
        if(fa[i]!=i)
            fa[i]=findfateher(fa,fa[i]);
        return fa[i];
    }
    //合并
    bool unionn(int fa[], int i, int j)
    {
    
    
        int fa_i=findfateher(fa,i);
        int fa_j=findfateher(fa,j);
        if(fa_i!=fa_j)
        {
    
    
            fa[fa_i]=fa_j;
            return true;
        }    
        return false;

    }
    int numSimilarGroups(vector<string>& strs) {
    
    
        int n=strs.size();
        int fa[n];
        for(int i=0;i<n;i++)
        {
    
    
            fa[i]=i;
        }
        //初始化,每个字符串都是独立的,所以存在n个字符组
        int nums=n;
        for(int i=0;i<n;i++)
        {
    
    
            for(int j=i+1;j<n;j++)
            {
    
       
                //判断两个字符串是否相似,并且之前是否已经联通,字符组数量减一
                if(similarity(strs[i],strs[j])&&unionn(fa,i,j))
                {
    
    
                    nums--;
                }
            }
        }
        return nums;
    }
};

剑指offer II 118 多余的边

原题

class Solution {
    
    
public:
    // 查找
    int findfa(int fa[], int i)
    {
    
    
        if(fa[i]!=i)
            fa[i]=findfa(fa,fa[i]);
        return fa[i];
    }
    // 合并
    bool unionn(int fa[],int i, int j)
    {
    
    
        int fa_i=findfa(fa,i);
        int fa_j=findfa(fa,j);
        if(fa_i!=fa_j)
        {
    
    
            fa[fa_i]=fa_j;
            return true;     //若之前不存在连接,则建立连接,返回true
        }
        return false;   //之前存在连接,返回false
    }
    vector<int> findRedundantConnection(vector<vector<int>>& edges) {
    
    
        int n=edges.size();
        int maxleaf=0;
        //查找最大节点的值
        for(int i=0;i<n;i++)
        {
    
    
            maxleaf=max(maxleaf,edges[i][0]);
            maxleaf=max(maxleaf,edges[i][1]);
        }
        int fa[maxleaf+1];  //此处记的加1,因为从1开始到n;
        for(int i=0;i<maxleaf+1;i++)
        {
    
    
            fa[i]=i;
        }
        int i;
        for(auto edge:edges)
        {
    
    
            if(!unionn(fa,edge[0],edge[1]))   //判断是否形成环
               return edge;
        }
        return  vector<int> {
    
    };
    }
};

剑指offer II 119 最长连续序列

原题

class Solution {
    
    
public:
    int findfa(unordered_map<int,int>& fa, int i)
    {
    
    
        if(fa[i]!=i)
            fa[i]=findfa(fa,fa[i]);
        return fa[i];
    }
    void unionn(unordered_map<int,int>& fa, unordered_map<int,int>& count,int i, int j)
    {
    
    
        int fa_i=findfa(fa,i);
        int fa_j=findfa(fa,j);
        if(fa_i!=fa_j)
        {
    
    
            fa[fa_i]=fa_j;
            count[fa_j]=count[fa_j]+count[fa_i];
        }
    }
    int longestConsecutive(vector<int>& nums) {
    
    
        unordered_map<int,int> fa;
        unordered_map<int,int> count;
        set<int> all;
        for(int i=0;i<nums.size();i++)
        {
    
    
            fa[nums[i]]=nums[i];
            count[nums[i]]=1;
            all.insert(nums[i]);
        }
        for(int i=0;i<nums.size();i++)
        {
    
    
            if(all.count(nums[i]-1)==1)
            {
    
    
                unionn(fa,count,nums[i],nums[i]-1);
            }
            if(all.count(nums[i]+1)==1)
            {
    
    
                unionn(fa,count,nums[i],nums[i]+1);
            }
        }
        int len=0;
        for(int i=0;i<nums.size();i++)
        {
    
    
            len=max(len,count[nums[i]]);
        }
        return len;
    }
};

单调栈

下一个更大元素

输入一个数组,返回等长数组,对应索引存储着下一个更大的元素,如果没有更大的元素,就存-1。

输入:nums=[ 2, 1, 2, 4, 3 ]    
返回:[ 4, 2, 4, -1, -1 ]
## lubuladong的算法小抄——p267
vector<int> nextGreaterElement(vector<int>& nums)
{
    
    
	vector<int> ans(nums.size());
	stack<int> s;
	for(int i=nums.size()-1;i>=0;i--)    //倒序
	{
    
    
		while(!s.empty()&&s.top()<=nums[i])
		{
    
    
			s.pop();      //数值小的出栈;
		}
		ans[i]=s.empty()?-1:s.top();		//大于该元素的第一个数值;
		s.push(nums[i]);	//进栈
	}
	return ans;
}

剑指 Offer II 038. 每日温度

请根据每日 气温 列表 temperatures ,重新生成一个列表,要求其对应位置的输出为:要想观测到更高的气温,至少需要等待的天数。如果气温在这之后都不会升高,请在该位置用 0 来代替。

输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]
class Solution {
    
    
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
    
    

        int len=temperatures.size();
        stack<int> s;
        vector<int> ans(len);
        for(int i=len-1;i>=0;i--)
        {
    
    
            while(!s.empty()&&temperatures[i]>=temperatures[s.top()])
            {
    
    
                s.pop();
            }
            ans[i]=s.empty()?0:s.top()-i;
            s.push(i);
        }
        return ans;
    }
};

柱状图中最大的矩形

class Solution {
    
    
public:
    int largestRectangleArea(vector<int>& heights) {
    
    
        int len=heights.size();
        vector<int> left(len), right(len);
        stack<int> s;
        for(int i=0;i<len;i++)
        {
    
    
            while(!s.empty()&&heights[i]<=heights[s.top()])
                s.pop();
            left[i]=s.empty()?-1:s.top();
            s.push(i);
        }
        s=stack<int> ();
        for(int i=len-1;i>=0;i--)
        {
    
    
            while(!s.empty()&&heights[i]<=heights[s.top()])
                s.pop();
            right[i]=s.empty()?len:s.top();
            s.push(i);
        }
        int max_m=0;
        for(int i=0;i<len;i++)
        {
    
    
            max_m=max(max_m,(right[i]-left[i]-1)*heights[i]);
        }
        return max_m;

    }
};

85. 最大矩形

class Solution {
    
    
public:
    int largestRectangleArea(vector<int>& heights) {
    
    
        int len=heights.size();
        vector<int> left(len), right(len,len);    //注意对right初始值赋len;
        stack<int> s;
        for(int i=0;i<len;i++)
        {
    
    
            while(!s.empty()&&heights[i]<=heights[s.top()])
            {
    
    
                right[s.top()]=i;
                s.pop();
            }    
            left[i]=s.empty()?-1:s.top();
            s.push(i);
        }
        int max_m=0;
        for(int i=0;i<len;i++)
        {
    
    
            max_m=max(max_m,(right[i]-left[i]-1)*heights[i]);
        }
        return max_m;

    }
};


class Solution {
    
    
public:
    int maximalRectangle(vector<vector<char>>& matrix) {
    
    
        int row=matrix.size();
        int col=matrix[0].size();
        vector<vector<int>> height(row,vector<int>(col,0));
        for(int i=0;i<row;i++)
            for(int j=0;j<col;j++)
            {
    
    
                if(matrix[i][j]=='1')
                    height[i][j]=(i==0?1:height[i-1][j]+1);
            }
        
        vector<int> left(col,0),right(col,col);
        stack<int> s;
        int ans=0;
        for(int i=0;i<row;i++)
        {
    
    
            for(int j=0;j<col;j++)
            {
    
    
                while(!s.empty()&&height[i][j]<s.top())
                {
    
    
                    right[s.top()]=j;
                    s.pop();
                }
                left[j]=s.empty()?-1:s.top();
                s.push(j);
            }
            s=stack<int> ();
            for(int k=0;k<col;k++)
            {
    
    
                ans=max(ans,(right[k]-left[k]-1)*height[i][k]);
            }
        }
        return ans;

    }
};

猜你喜欢

转载自blog.csdn.net/weixin_42213421/article/details/124332367