1.leetcode中出现not all control paths return a value
参考:https://blog.csdn.net/ping_lvy/article/details/84402064
在leetcode上做题,一直提示这个,原来是因为各分支必须有返回值
题目:判断链表中是否有环
https://www.nowcoder.com/practice/650474f313294468a4ded3ce0f7898b9?tpId=188&tqId=37531&rp=1&ru=%2Factivity%2Foj&qru=%2Fta%2Fjob-code-high-week%2Fquestion-ranking&tab=answerKey
快慢指针同步移动,最后判断是否重合
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool hasCycle(ListNode *head) {
ListNode *fast=head;
ListNode *slow=head;
while(fast!=NULL&&fast->next!=NULL){
fast=fast->next->next;
slow=slow->next;
if(fast==slow)return true;
}
return false;
}
};
用两个栈来实现一个队列
链接:https://www.nowcoder.com/practice/54275ddae22f475981afa2244dd448c6?tpId=188&tqId=37536&rp=1&ru=%2Factivity%2Foj&qru=%2Fta%2Fjob-code-high-week%2Fquestion-ranking&tab=answerKey
class Solution
{
public:
void push(int node) {
stack1.push(node);
}
int pop() {
if(stack2.size()==0)
while(stack1.empty()!=1){
stack2.push(stack1.top());
stack1.pop();
}
int x=stack2.top();
stack2.pop();
return x;
}
private:
stack<int> stack1;
stack<int> stack2;
};
寻找第K大
链接:
https://www.nowcoder.com/practice/e016ad9b7f0b45048c58a9f27ba618bf?tpId=188&tqId=37518&rp=1&ru=%2Factivity%2Foj&qru=%2Fta%2Fjob-code-high-week%2Fquestion-ranking&tab=answerKey
class Solution {
public:
void find_kth(vector<int>& a,int left,int right,int K){//必须用&不然每次都是开辟新的,最后最外层等于没有修改
int l=left,r=right;
int mid=a[(l+r)/2];
while(l<=r){
while(a[l]<mid)l++;
while(a[r]>mid)r--;
if(l<=r){
swap(a[l],a[r]);
l++;
r--;
}
}
if(r>left&&K<=r)find_kth(a,left,r,K);
if(l<right&&K>=l)find_kth(a,l,right,K);
}
int findKth(vector<int> a, int n, int K) {
// write code here
K--;
find_kth(a,0,n-1,n-K-1);//注意是第k大
return a[n-K-1];
}
};
最大连续1的个数 III
双指针
链接:https://leetcode-cn.com/problems/max-consecutive-ones-iii/
题目大意:给定一个由若干 0 和 1 组成的数组 A,我们最多可以将 K 个值从 0 变成 1 。
返回仅包含 1 的最长(连续)子数组的长度。
class Solution {
public:
int longestOnes(vector<int>& A, int K) {
int n=A.size();
int l=0;
int r=-1;
int ans=0;
while(r<n-1&&(A[r+1]==1||K>0)){
r++;
if(A[r]==0)K--;
}
ans=max(ans,r-l+1);
for(int l=1;l<n;l++){
if(l-1>r)r++;
else if(A[l-1]==0)K++;
while(r<n-1&&(A[r+1]==1||K>0)){
r++;
if(A[r]==0)K--;
}
ans=max(ans,r-l+1);
}
return ans;
}
};
反转链表
链接:https://leetcode-cn.com/problems/reverse-linked-list/
反转一个单链表。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode *head) {
ListNode *pre=NULL;
if(head==NULL)return head;
for(;;){
ListNode *next=head->next;
head->next=pre;
if(next==NULL)break;
pre=head;
head=next;
}
return head;
}
};
二叉树的最近公共祖先
https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/submissions/
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
map<int,TreeNode*>fa;
map<int,bool>flag;
void dfs(TreeNode* now){
if(now->left!=NULL){
fa[now->left->val]=now;
dfs(now->left);
}
if(now->right!=NULL){
fa[now->right->val]=now;
dfs(now->right);
}
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
fa[root->val]=NULL;
dfs(root);
while(p!=NULL){
flag[p->val]=true;
p=fa[p->val];
}
while(flag[q->val]==NULL)q=fa[q->val];
return q;
}
};
三数之和
https://leetcode-cn.com/problems/3sum/
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
int n=nums.size();
sort(nums.begin(),nums.end());
vector<vector<int>> ans;
for(int i=0;i<n-2;i++){
if(i>0&&nums[i]==nums[i-1])continue;
int k=n-1;
for(int j=i+1;j<n-1;j++){
if(j-1>i&&nums[j]==nums[j-1])continue;
while(k>j+1&&nums[i]+nums[j]+nums[k]>0)k--;
if(k<=j)break;
if(nums[i]+nums[j]+nums[k]==0){
ans.push_back({nums[i],nums[j],nums[k]});
}
}
}
return ans;
}
};
LRU 缓存机制
https://leetcode-cn.com/problems/lru-cache/
运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制 。
实现 LRUCache 类:
LRUCache(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存
int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
void put(int key, int value) 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字-值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。
class LRUCache {
struct node{
int key,val;
}q[100000];
int r=0,cnt=0;
public:
LRUCache(int capacity) {
r=0;
cnt=capacity;
}
int get(int key) {
for(int i=1;i<=r;i++)
if(q[i].key==key){
node temp=q[i];
for(int j=i;j<r;j++)q[j]=q[j+1];
q[r]=temp;
return temp.val;
}
return -1;
}
void put(int key, int value) {
for(int i=1;i<=r;i++){
if(q[i].key==key){
q[i].val=value;
node temp=q[i];
for(int j=i;j<r;j++)q[j]=q[j+1];
q[r]=temp;
return;
}
}
if(r<cnt){
r++;
q[r].key=key;
q[r].val=value;
return;
}else{
for(int i=1;i<r;i++)q[i]=q[i+1];
q[r].key=key;
q[r].val=value;
}
}
};
/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache* obj = new LRUCache(capacity);
* int param_1 = obj->get(key);
* obj->put(key,value);
*/
字符串的排列
https://leetcode-cn.com/problems/permutation-in-string/
给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的排列。
换句话说,第一个字符串的排列之一是第二个字符串的子串。
题解:直接用hash进行处理
class Solution {
public boolean checkInclusion(String s1, String s2) {
int MO=1000000007;
int len1=s1.length();
int len2=s2.length();
if(len1>len2)return false;
int hash1=0,hash2=0;
for(int i=0;i<len1;i++)hash1=(hash1+s1.charAt(i)*s1.charAt(i)*s1.charAt(i))%MO;
for(int i=0;i<len1;i++)hash2=(hash2+s2.charAt(i)*s2.charAt(i)*s2.charAt(i))%MO;
if(hash1==hash2)return true;
for(int i=len1;i<len2;i++){
hash2+=s2.charAt(i)*s2.charAt(i)*s2.charAt(i);
hash2-=s2.charAt(i-len1)*s2.charAt(i-len1)*s2.charAt(i-len1);
hash2=(hash2+MO)%MO;
if(hash1==hash2)return true;
}
return false;
}
}
俄罗斯套娃信封问题
https://leetcode-cn.com/problems/russian-doll-envelopes/
给定一些标记了宽度和高度的信封,宽度和高度以整数对形式 (w, h) 出现。当另一个信封的宽度和高度都比这个信封大的时候,这个信封就可以放进另一个信封里,如同俄罗斯套娃一样。
请计算最多能有多少个信封能组成一组“俄罗斯套娃”信封(即可以把一个信封放到另一个信封里面)。
**主要是对vector数组使用了判断条件的快排**
class Solution {
public:
int maxEnvelopes(vector<vector<int>>& envelopes) {
sort(envelopes.begin(),envelopes.end(),
[](const vector<int> &a,const vector<int> &b){
return a[0]<b[0];
});
int n=envelopes.size();
int ans=0,f[110000];
for(int i=0;i<n;i++){
f[i]=1;
for(int j=0;j<i;j++){
if(envelopes[i][0]>envelopes[j][0]&&envelopes[i][1]>envelopes[j][1]){
f[i]=max(f[i],f[j]+1);
}
}
ans=max(ans,f[i]);
}
return ans;
}
};
链表快排
https://www.luogu.com.cn/problem/P1177
用链表实现快速排序
#include<bits/stdc++.h>
using namespace std;
struct node{
int x;
node *next,*pre;
};
int n,x;
void kspx(node *head,node *tail,int left,int right){
node *h=head,*t=tail;
int l=left,r=right;
int ra=rand()%(r-l+1);
for(int i=1;i<=ra;i++)h=h->next;
int mid=h->x;
h=head;
while(l<=r){
while(h->x<mid)h=h->next,l++;
while(t->x>mid)t=t->pre,r--;
if(l<=r){
swap(h->x,t->x);
h=h->next;
t=t->pre;
l++;
r--;
}
}
if(r>left)kspx(head,t,left,r);
if(l<right)kspx(h,tail,l,right);
}
int main(){
cin>>n;
node *head=new node;
//注意不能node *head,*tail写成这样,这样会出现RunTimeError在luogu上,估计是有可能
//head和tail没有new node,所以开成了同一个
node *tail=new node;
tail=head;
for(int i=1;i<=n;i++){
cin>>x;
node *p=new node;
p->x=x;
tail->next=p;
p->pre=tail;
tail=tail->next;
}
head=head->next;
kspx(head,tail,1,n);
while(head!=NULL){
cout<<head->x<<" ";
head=head->next;
}
cout<<endl;
return 0;
}
字节后端开发,视频架构 三面
m个队列,每个队列n个元素,每个队列都是单调递增的,求所有元素的前k小。
可以用个小根堆维护当前m个队列的队首,每次选出min,然后选择下一个加入堆,重复k次。复杂度klogm。
也可以用大根堆维护,当新加入的元素大于堆顶,直接放弃这个队列(因为后面的肯定不可能),如果可以,则需要退出一个(退出的那个队列之后的元素肯定也不需要了,也可以直接pass那个队列).
#include <bits/stdc++.h>
using namespace std;
struct node{
int val,id,rank;
bool operator <(const node &now)const{//重载运算符,以val为键值维护小根堆
return val>now.val;
}
};
priority_queue<node>heap;//注意一下优先队列的定义
int n,m,k,a[1110][1100];
int main(){
cin>>m>>n;
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++)
cin>>a[i][j];
}
for(int i=1;i<=m;i++){
heap.push((node){a[i][1],i,1});
}
cin>>k;
while(k--){
node now=heap.top();
heap.pop();
cout<<now.val<<" ";
if(now.rank<n){
now.rank++;
heap.push((node){a[now.id][now.rank],now.id,now.rank});//(node)直接把后面的三个元素打包成一个node型
}
}
return 0;
}
介绍一下项目中的数据库表项情况
介绍一下点击双方视频面试链接进入房间的步骤,描述一下之后某方点击发起视频会话的整个过程。
我的理解是从url显示页面,之后类似游戏大厅服务器把房间激活。
知乎中搜索某一个问题,会有相关的喜好推荐,这些喜好推荐可以继续点击,不断重复这个过程。设计一个分布式的系统,可以把所有相关的内容都爬下来。
个人设计:一个队列,一个Python脚本(根据一个url得到一个所有url的集合),然后所有服务器上都放一个队列,bfs每次取出头部,然后获得一些找到的url,发给其它所有机器,注意去重,用hash,注意一下分布式的hash判重数据同步性。
三个线程依次输出1-100
待补充
hulu一面:
图片上传的逻辑
支付的过程
平时怎么学习新技术
算法题 单线程 CPU:https://leetcode-cn.com/problems/single-threaded-cpu/
vector在本地调试可以这样,vector里面是vector
#include<bits/stdc++.h>
using namespace std;
struct data{
int dur,id;
bool operator <(const data b)const{
if(dur>b.dur)return 1;
if(dur<b.dur)return 0;
return id>b.id;
}
};
bool taskcmp(vector<int> &a,vector<int> &b){
return a[0]<b[0];
}
vector<int> getOrder(vector<vector<int>> task){
int n=task.size();
sort(task.begin(),task.end(),taskcmp);
long long time=0;
priority_queue<data>q;
vector<int>res;
int mark=0;
for(;;){
while(mark<n&&task[mark][0]<=time){
q.push({task[mark][1],task[mark][2]});
mark++;
}
if(q.size()>0){
time+=q.top().dur;
res.push_back(q.top().id);
q.pop();
}else{
if(mark==n)break;
time=task[mark][0];
}
}
return res;
}
int main(){
int n;
cin>>n;
vector<vector<int>> tasks;
for(int i=0;i<n;i++){
int st,du;
vector<int> now;
cin>>st>>du;
now.push_back(st);
now.push_back(du);
now.push_back(i);
tasks.push_back(now);
}
vector<int>ans;
ans=getOrder(tasks);
for(int i=0;i<ans.size();i++)cout<<ans[i]<<" ";
cout<<endl;
return 0;
}
或者这样 vector里面是结构体
#include<bits/stdc++.h>
using namespace std;
struct data{
int start,duration,id;
bool operator<(const data &b)const{
if(duration>b.duration)return 1;
if(duration<b.duration)return 0;
return id>b.id;
}
};
bool taskcmp(data a,data b){
return a.start<b.start;
}
vector<int> getOrder(vector<data> &task){如果加&,那么里面的task实际上就是外面的tasks,里面的修改外面的也修改
sort(task.begin(),task.end(),taskcmp);
priority_queue<data>q;
vector<int>res;
long long time=0;
int n=task.size();
int mark=0;
while(1){
while(mark<n&&time>=task[mark].start){
q.push(task[mark]);
mark++;
}
if(q.size()>0){
res.push_back(q.top().id);
time+=q.top().duration;
q.pop();
}else{
if(mark==n)break;
time=task[mark].start;
}
}
return res;
}
int main(){
vector<data>tasks;
int n;
cin>>n;
for(int i=0;i<n;i++){
int start,duration;
cin>>start>>duration;
tasks.push_back({start,duration,i});
}
vector<int>ans;
ans=getOrder(tasks);
for(int i=0;i<ans.size();i++)cout<<ans[i]<<" ";
cout<<endl;
return 0;
}