第一题 栈排序OJ
请编写一个程序,按升序对栈进行排序(即最大元素位于栈顶),要求最多只能使用一个额外的栈存放临时数据,但不得将元素复制到别的数据结构中。
给定一个int[] numbers(C++中为vector<int>),其中第一个元素为栈顶,请返回排序后的栈。请注意这是一个栈,意味着排序过程中你只能访问到最后一个元素。
测试样例:[1,2,3,4,5]
返回:[5,4,3,2,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=[]
- 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]
- 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]
- 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]
- 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]
- 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]
更为直观的数据:
- 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=[]
- 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]
- 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]
- 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]
- 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]
- 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]
- 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]
- 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]
- 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]
- 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]
- 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 乘数num1位数为M,被乘数num2位数为N,num1×num2的结果res最大总位数为M+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;
}