0805笔试的编程题答案

第一题 栈排序OJ

请编写一个程序,按升序对栈进行排序(即最大元素位于栈顶),要求最多只能使用一个额外的栈存放临时数据,但不得将元素复制到别的数据结构中。

给定一个int[] numbers(C++中为vector&ltint>),其中第一个元素为栈顶,请返回排序后的栈。请注意这是一个栈,意味着排序过程中你只能访问到最后一个元素。

测试样例:[1,2,3,4,5]
返回:[5,4,3,2,1]

解题思路

Created with Raphaël 2.2.0 开始 创建辅助栈r numbers数组是否为空? 反转r数组 结束 将numbers数组中的最后一个变量存入临时变量temp中并删除 r数组不为空 && r的最后一位>temp? 将r数组中的最后一个变量存入numbers中并删除 将temp存入r中,重返最外层循环 yes no yes no

题目中的数据:

  1. n u m b e r s = [ 1 , 2 , 3 , 4 , 5 ] , r = [ ] numbers = [1,2,3,4,5],r=[] numbers=[1,2,3,4,5],r=[]
  2. n u m b e r s = [ 2 , 3 , 4 , 5 ] , r = [ 1 ] numbers = [2,3,4,5],r=[1] numbers=[2,3,4,5]r=[1]
  3. n u m b e r s = [ 3 , 4 , 5 ] , r = [ 1 , 2 ] numbers = [3,4,5],r=[1,2] numbers=[3,4,5]r=[1,2]
  4. n u m b e r s = [ 4 , 5 ] , r = [ 1 , 2 , 3 ] numbers = [4,5],r=[1,2,3] numbers=[4,5]r=[1,2,3]
  5. n u m b e r s = [ 5 ] , r = [ 1 , 2 , 3 , 4 ] numbers = [5],r=[1,2,3,4] numbers=[5]r=[1,2,3,4]
  6. n u m b e r s = [ ] , r = [ 1 , 2 , 3 , 4 , 5 ] numbers = [],r=[1,2,3,4,5] numbers=[],r=[1,2,3,4,5]

更为直观的数据:

  1. n u m b e r s = [ 4 , 2 , 1 , 5 , 3 ] , r = [ ] numbers = [4,2,1,5,3],r=[] numbers=[4,2,1,5,3],r=[]
  2. n u m b e r s = [ 2 , 1 , 5 , 3 ] , r = [ 4 ] numbers = [2,1,5,3],r=[4] numbers=[2,1,5,3]r=[4]
  3. n u m b e r s = [ 4 , 1 , 5 , 3 ] , r = [ 2 ] numbers = [4,1,5,3],r=[2] numbers=[4,1,5,3]r=[2]
  4. n u m b e r s = [ 1 , 5 , 3 ] , r = [ 2 , 4 ] numbers = [1,5,3],r=[2,4] numbers=[1,5,3]r=[2,4]
  5. n u m b e r s = [ 2 , 4 , 5 , 3 ] , r = [ 1 ] numbers = [2,4,5,3],r=[1] numbers=[2,4,5,3]r=[1]
  6. n u m b e r s = [ 4 , 5 , 3 ] , r = [ 1 , 2 ] numbers = [4,5,3],r=[1,2] numbers=[4,5,3]r=[1,2]
  7. n u m b e r s = [ 5 , 3 ] , r = [ 1 , 2 , 4 ] numbers = [5,3],r=[1,2,4] numbers=[5,3]r=[1,2,4]
  8. n u m b e r s = [ 3 ] , r = [ 1 , 2 , 4 , 5 ] numbers = [3],r=[1,2,4,5] numbers=[3]r=[1,2,4,5]
  9. n u m b e r s = [ 4 , 5 ] , r = [ 1 , 2 , 3 ] numbers = [4,5],r=[1,2,3] numbers=[4,5]r=[1,2,3]
  10. n u m b e r s = [ 5 ] , r = [ 1 , 2 , 3 , 4 ] numbers = [5],r=[1,2,3,4] numbers=[5]r=[1,2,3,4]
  11. n u m b e r s = [ ] , r = [ 1 , 2 , 3 , 4 , 5 ] numbers = [],r=[1,2,3,4,5] numbers=[],r=[1,2,3,4,5]

代码展示

class TwoStacks {
public:
	vector<int> twoStacksSort(vector<int> numbers) {	
	    vector<int> r;
	    while(!numbers.empty()) {
	        int temp = numbers.back();
	        numbers.pop_back();
	        while ( !r.empty() && r.back() > temp) {
	            numbers.push_back(r.back());
	            r.pop_back();
	        }
	        r.push_back(temp);
	    }
	    reverse(r.begin(),r.end());
	    return r;
	}
};

相似题目

栈排序。 编写程序,对栈进行排序使最小元素位于栈顶。最多只能使用一个其他的临时栈存放数据,但不得将元素复制到别的数据结构(如数组)中。该栈支持如下操作:push、pop、peek 和 isEmpty。当栈为空时,peek 返回 -1。

示例1:

输入:
[“SortedStack”, “push”, “push”, “peek”, “pop”, “peek”]
[[], [1], [2], [], [], []]
输出:
[null,null,null,1,null,2]

示例2:

输入:
[“SortedStack”, “pop”, “pop”, “push”, “pop”, “isEmpty”]
[[], [], [], [1], [], []]
输出:
[null,null,null,null,null,true]

说明:

栈中的元素数目在[0, 5000]范围内。

提示

  • 排序数组的一种方法是遍历数组,并将每个元素按排序顺序插入到一个新数组中。你可以用一个栈实现吗?
  • 假设二级栈已排序。你能按顺序插入元素吗?你可能需要一些额外的存储空间。你可以使用什么额外的存储?
  • 保持二级栈的排序顺序,最大的元素在顶部。使用主栈进行额外的存储。

代码展示

class SortedStack {
public:
    stack<int>s1;//原栈为降序
    stack<int>s2;//辅助栈为升序
    SortedStack() {

    }
    
    void push(int val) {
        while(!s2.empty() && s2.top() > val){//辅助栈中存在比val大的值
            s1.push(s2.top());
            s2.pop();
        }
        while(!s1.empty() && s1.top() < val){//原栈中有比val小的值
            s2.push(s1.top());
            s1.pop();
        }
        s1.push(val);
    }
    
    void pop() {
        while(!s2.empty()){//清空辅助栈
            s1.push(s2.top());
            s2.pop();
        }
        if(!s1.empty()) s1.pop();
    }
    
    int peek() {
        while(!s2.empty()){//清空辅助栈
            s1.push(s2.top());
            s2.pop();
        }
        if(!s1.empty()) return s1.top();
        else return -1;
    }
    
    bool isEmpty() {
        return s1.empty() && s2.empty();
    }
};

第二题 字符串相乘OJ

给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。

示例 1:

输入: num1 = “2”, num2 = “3”
输出: “6”

示例 2:

输入: num1 = “123”, num2 = “456”
输出: “56088”

示例 3:

输入: num1 = “39134761537489194655544”, num2 = “83648919651354818901”
输出: “3273580523424364621101927664042199195637144”

说明:

num1 和 num2 的长度小于110。
num1 和 num2 只包含数字 0-9。
num1 和 num2 均不以零开头,除非是数字 0 本身。
不能使用任何标准库的大数类型(比如 BigInteger)或直接将输入转换为整数来处理。

解题思路

该算法是通过两数相乘时,乘数某位与被乘数某位相乘,与产生结果的位置的规律来完成。具体规律如下:

  • 乘 数 n u m 1 位 数 为 M , 被 乘 数 n u m 2 位 数 为 N , n u m 1 × n u m 2 的 结 果 r e s 最 大 总 位 数 为 M + N 乘数 num1 位数为 M,被乘数 num2 位数为 N, num1\times num2 的结果 res 最大总位数为 M+N num1Mnum2Nnum1×num2resM+N
  • n u m 1 [ i ] × n u m 2 [ j ] 的 结 果 为 t e m p ( 位 数 为 两 位 , " 0 x " , " x y " 的 形 式 ) , 其 第 一 位 位 于 r e s [ i + j ] , 第 二 位 位 于 r e s [ i + j + 1 ] 。 num1[i]\times num2[j] 的结果为temp(位数为两位,"0x","xy"的形式),其第一位位于 res[i+j],第二位位于 res[i+j+1]。 num1[i]×num2[j]temp("0x","xy")res[i+j]res[i+j+1]

结合下图更容易理解
竖式计算

代码展示

class Solution {
public:
    string multiply(string num1, string num2) {
        int n1=num1.size();
        int n2=num2.size();
        string res(n1+n2,'0');
        for(int i=n2-1;i>=0;i--){
            for(int j=n1-1;j>=0;j--){
                int temp=(res[i+j+1]-'0')+(num1[j]-'0')*(num2[i]-'0');
                res[i+j+1]=temp%10+'0';
                res[i+j]+=temp/10; 
            }
        }
        
        for(int i=0;i<n1+n2;i++){
            if(res[i]!='0')
                return res.substr(i);
        }
        return "0";
    }
};

第三题 DNA序列OJ

描述:

一个DNA序列由A/C/G/T四个字母的排列组合组成。G和C的比例(定义为GC-Ratio)是序列中G和C两个字母的总的出现次数除以总的字母数目(也就是序列长度)。在基因工程中,这个比例非常重要,因为高的GC-Ratio可能是基因的起始点。

给定一个很长的DNA序列,以及要求得最小子序列长度,研究人员经常会需要在其中找出GC-Ratio最高的子序列。

输入:

输入一个string型基因序列,和int型子串的长度

输出:

找出GC比例最高的子串

样例输入:

AACTGTGCACGACCTGA , 5
样例输出:GCACG

解题思路

暴力破解,AC。
当初笔试的时候没有写正确,因为我以为题目要求的是最小子序列长度为n ( ≥ n ) (\geq n) (n)而不是固定为n,因此许多测试样例都没有通过。
这道题只要找出长度为n的子序列,之后找到CG含量最多的第一个子序列输出就好了。

代码展示

#include <iostream>
#include <string>
using namespace std;
int main(void)
{
	string str,outstr="";
	int n=1,i=0,j=0;
	cin>>str>>n;
	
	int times=str.length()-n+1;
	int maxGC=0;
	int GC;
	for(i=0;i<times;i++)
	{
		GC=0;
		for(j=0;j<n;j++)
		{
			if(str[i+j]=='G'||str[i+j]=='C')
				GC++;
		}
		if(GC>maxGC)
		{
			maxGC=GC;
			outstr=str.substr(i,n);
		}
	}
	cout<<outstr;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值