面试笔试算法类题目

一些算法题写在这里吧:

1: :100层楼,有两个玻璃球,有唯一一层,从该楼层及以下楼层扔下玻璃球不会碎,从该楼层以上扔玻璃球会碎,请用用两个玻璃球找出该层(最小的时间复杂度)。
关于这道题来说我们假设我们需要k次,那么第一次肯定是在第k层,加入破了,那么向下找就是k-1+1次
如果没破,向上加k-1层,以此类推,加k-2,k-3,k-4…
得等式:k(1+k)/2 >=100
k = 14
扩展版本:
玻璃球个数为x个,求最小次数:
设dp[i][j]为i个球实验了j次可以测定的最高楼层
转移方程为dp[i][j] = dp[i-1][j-1] +dp[i][j-1]+1

 
#include <iostream>
#include <vector>
#include <list>
#include <string>
#include <typeinfo>
#include "db3.cpp"
#include<cstring>
using namespace std;
long long dp[100+4][100+4];
int main()
{
	for(int i = 1;i<=100;i++){
		for(int j = 1;j<=100;j++){
			dp[i][j] = dp[i][j-1]+dp[i-1][j-1]+1;	
		}
	}
	for(int i = 1;i<=100;i++){
		if(dp[2][i]>=100){
			cout<<i<<endl;
			return 0;
		}
	}
}

2:双端链表

 
#include <iostream>
#include <vector>
#include <list>
#include <string>
#include <typeinfo>
#include "db3.cpp"
#include<cstring>
#include<memory>
using namespace std;
struct node
{
	int data;
	shared_ptr<node> pre;
	shared_ptr<node> nxt;
	node():data(0),pre(0),nxt(0){};
	node(int data):data(data),pre(0),nxt(0){};
};
class LIST
{
	public:
	int size;
	shared_ptr<node>head=nullptr;
	shared_ptr<node>tail=nullptr;
public:
	LIST() = default;
	LIST(int len)
	{
		head = make_shared<node>();
		shared_ptr<node>now = head;
		for(int i = 0;i<len;i++){
			cout<<"fsfsfsf"<<endl;
			now->nxt = make_shared<node>();
			now->nxt->pre = now;
			now = now->nxt;
		}
		tail = now;
	}
	LIST(const LIST &a)
	{
		head = make_shared<node>();
		cout<<head.use_count()<<endl;
		shared_ptr<node>now = head;
		shared_ptr<node>now2 = a.head;
		while(now2){
			now->nxt = make_shared<node>(now2->data);
			now->nxt->pre = now;
			now = now->nxt;
			now2 = now2->nxt;
		}
		cout<<head.use_count()<<endl;

		tail = now;
cout<<head.use_count()<<endl;

	}
	void insert(shared_ptr<node> f,int val)
	{
		if(f){
			if(f->nxt==nullptr){
				f->nxt = make_shared<node>(val);
				f->nxt->pre = f;
			}
			else{
				shared_ptr<node>tmp = make_shared<node>(val);
				f->nxt->pre = tmp;
				tmp->nxt = f->nxt;
				f->nxt = tmp;
				tmp->pre = f;
			}
		}
	}
	void erase(shared_ptr<node>&f)
	{
		if(f){
			cout<<f.use_count()<<endl;
			if(f->nxt)
			{
				f->nxt->pre = f->pre;
			}
			if(f->pre)
			{
				f->pre->nxt = f->nxt;
			}
			f = nullptr;
			cout<<head.use_count()<<endl;

		}
	}
};
int main()
{
	LIST a(10);
	LIST b(a);
	cout<<b.head.use_count()<<endl;
	b.erase(b.head);
}

求单链表中结点的个数

#include<iostream>
#include<string>
#include<algorithm>
#include<cstring>
#include<memory>
using namespace std;
struct node
{
	int va;
	node *nxt;
	node(int v):va(v),nxt(nullptr){};
};
int n;
int count(node *head)
{
	if(head==nullptr) return 0;
	node *now = head;
	int ret = 0;
	while(now)
	{
		ret++;
		now = now->nxt;
	}
	return ret;
}
int main()
{	
	cin>>n;
	node *head = new node(0);
	int tmpva = 1;
	node *now = head;
	for(int i = 0;i<n;i++){
		now->nxt = new node(tmpva++);
		now = now->nxt;
	}
	cout<<count(head->nxt)<<endl;
}

将单链表反转

#include
#include
#include
#include
#include
using namespace std;
struct node
{
int va;
node *nxt;
node(int v):va(v),nxt(nullptr){};
};
int n;
int count(node *head)
{
if(headnullptr) return 0;
node *now = head;
int ret = 0;
while(now)
{
ret++;
now = now->nxt;
}
return ret;
}
void display(node *head)
{
node now = head;
while(now)
{
cout<va<<endl;
now = now->nxt;
}
}
node
reveser(node *head)
{
if(head
nullptr||head->nxt==nullptr){
return head;
}
node *now = head;
node now2 = nullptr;
while(now)
{
node
tmp = now->nxt;
now->nxt = now2;
now2 = now;
now = tmp;
}
return now2;
}
int main()
{
cin>>n;
node *head = new node(0);
int tmpva = 1;
node *now = head;
for(int i = 0;i<n;i++){
now->nxt = new node(tmpva++);
now = now->nxt;
}
cout<<count(head->nxt)<<endl;
head->nxt = reveser(head->nxt);
display(head->nxt);
}

查找单链表中的倒数第K个结点(k > 0)

#include<iostream>
#include<string>
#include<algorithm>
#include<cstring>
#include<memory>
using namespace std;
struct node
{
	int va;
	node *nxt;
	node(int v):va(v),nxt(nullptr){};
};
int n;
int count(node *head)
{
	if(head==nullptr) return 0;
	node *now = head;
	int ret = 0;
	while(now)
	{
		ret++;
		now = now->nxt;
	}
	return ret;
}
void display(node *head)
{
	node *now = head;
	while(now)
	{
		cout<<now->va<<endl;
		now = now->nxt;
	}
}
node* reveser(node *head)
{
	if(head==nullptr||head->nxt==nullptr){
		return head;
	}
	node *now = head;
	node *now2 = nullptr;
	while(now)
	{
		node* tmp = now->nxt;
		now->nxt = now2;
		now2 = now;
		now = tmp;
	}
	return now2;
}
node * find_k(node* head,int k)
{
	node* now= head;
	if(k<=0||head==nullptr)return nullptr;
	node *b1 = head;
	node *b2 = head;
	while(k>1&&b2)
	{
		k--;
		b2 = b2->nxt;
	}
	if(k>1||b2==nullptr){
		return nullptr;
	}
	while(b2->nxt){
		b1 = b1->nxt;
		b2 = b2->nxt;
	}
	return b1;
}
int main()
{	
	cin>>n;
	node *head = new node(0);
	int tmpva = 1;
	node *now = head;
	for(int i = 0;i<n;i++){
		now->nxt = new node(tmpva++);
		now = now->nxt;
	}
	cout<<find_k(head->nxt,1)->va<<endl;
}

查找单链表的中间结点

#include<iostream>
#include<string>
#include<algorithm>
#include<cstring>
#include<memory&
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值