C++编程1

1.给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。

分析:

  1. 字符'a'-'z'(如果有大写转化为小写即可)
  2. 使用大小为26的整型数Num_char组int Num_char[26]]存储每个字符出现的次数(初始化为0)
  3. 使用大小为26的整型数组int Pos_char[26]存储字符串中出现的每个字符出现的最早位置(初始化为-1)
  4. 遍历字符串更新Num_char和Pos_char数组
  5. 遍历Num_char和Pos_char数组,找到Num_char[i]=1且Pos_char[i]最小的i,返回

代码:

int main()
{
    string s="";
    char c=cin.get();
    while(c!='\n'){
        if(c=='\''||c==','||c=='.'||c==' '){
            s=s; }else{ s+=c; } c=cin.get(); } int n=s.size(); int Pos_start[26]; int num_char[26]; for(int i=0;i<26;i++){ Pos_start[i]=-1; num_char[i]=0; } for(int i=0;i<n;i++){ int tmp=s[i]-'a'; num_char[tmp]++; if(Pos_start[tmp]==-1){ Pos_start[tmp]=i; } } int index=n; for(int i=0;i<26;i++){ if(num_char[i]==1){ if(Pos_start[i]<index){ index=Pos_start[i]; } } } cout<<index<<endl; return 0; }

2.最长可整合子数组的长度

题目描述

先给出可整合数组的定义:如果一个数组在排序之后,每相邻两个数的差的绝对值都为1,或者该数组长度为1,则该数组为可整合数组。例如,[5, 3, 4, 6, 2]排序后为[2, 3, 4, 5, 6],符合每相邻两个数差的绝对值都为1,所以这个数组为可整合数组
给定一个数组arr, 请返回其中最大可整合子数组的长度。例如,[5, 5, 3, 2, 6, 4, 3]的最大可整合子数组为[5, 3, 2, 6, 4],所以请返回5
[要求]
时间复杂度为 O(n^2)O(n2),空间复杂度为O(n)O(n)

输入描述:

第一行一个整数N,表示数组长度
第二行N个整数,分别表示数组内的元素

输出描述:

 输出一个整数,表示最大可整合子数组的长度

分析:

  1. 求排序后最长递增且间隔为1的子序列的长度
  2. 使用set<int> A有序且无重复存储数组
  3. 定义一维数组dp[A.size()],dp[i]存储的是该位置前最长递增且间隔为1的子序列的长度。
  4. 如果(A[i]-A[i-1]==1) dp[i]=dp[i-1]+1;否则dp[i]=1;

代码:

#include <iostream>
#include<set>
using namespace std;

int main()
{
    int N;
    cin>>N;
    set<int> A;
    int a;
    for(int i=0;i<N;i++){
        cin>>a;
        A.insert(a);
    }
    int len=A.size();
    if(len<=1){
        cout<<len<<endl;
        return 0;
    }
    int dp[len];

    dp[0]=1;
    int res=1;
    set<int>::iterator it=A.begin();
    it++;
    int i=1;
    for(;it!=A.end();it++,i++){
        if(*(it--)-*it==1){
            dp[i]=dp[i-1]+1;
            if(dp[i]>res){
                res=dp[i];
            }
        }else{
            dp[i]=1;
        }
        it++;
    }
    cout<<res<<endl;

    return 0;
}
View Code

3.不重复打印排序数组中相加和为给定值的所有二元组

题目描述

给定排序数组arr和整数k,不重复打印arr中所有相加和为k的不降序二元组
例如, arr = [-8, -4, -3, 0, 1, 2, 4, 5, 8, 9], k = 10,打印结果为:
1, 9
2, 8
[要求]
时间复杂度为 O(n)O(n),空间复杂度为O(1)O(1)

输入描述:

第一行有两个整数n, k
接下来一行有n个整数表示数组内的元素

输出描述:

输出若干行,每行两个整数表示答案
按二元组从小到大的顺序输出(二元组大小比较方式为每个依次比较二元组内每个数)

分析:

  1. 数组有序,所以可以用两个指针i,j分别从首尾遍历数组A[n];
  2. 如果A[i]+A[j]>给定值k,说明后面的指针应该往前移,使和减小,j--;
  3. 如果A[i]+A[j]<给定值k,说明前面的指针i应该往后移,使和增大,i++;
  4. 如果A[i]+A[j]=给定值k,输出A[i] A[j];同时看数组中是否有和A[i]、A[j]值相同的元素,有则跳过。

代码:

#include <iostream>
#include<vector>

using namespace std;

int main()
{
    int n,k;
    cin>>n>>k;
    vector<int> A(n);
    for(int i=0;i<n;i++){
        cin>>A[i];
    }
    int low=0;
    int high=n-1;
    while(low<high){
        if(A[low]+A[high]==k){
            cout<<A[low]<<" "<<A[high]<<endl;
            while(low+1<n&&A[low]==A[low+1])low++;
            while(high-1>=0&&A[high]==A[high-1])high--;
            low++;
            high--;
        }else if(A[low]+A[high]>k){
            high--;
        }else{
            low++;
        }
    }

    return 0;
}
View Code

4、设计getMin功能的栈

题目描述

实现一个特殊功能的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作。

输入描述:

第一行输入一个整数N,表示对栈进行的操作总数。

下面N行每行输入一个字符串S,表示操作的种类。

如果S为"push",则后面还有一个整数X表示向栈里压入整数X。

如果S为"pop",则表示弹出栈顶操作。

如果S为"getMin",则表示询问当前栈中的最小元素是多少。

输出描述:对于每个getMin操作,输出一行表示当前栈中的最小元素是多少。
示例1

输入

6
push 3
push 2
push 1
getMin
pop
getMin
输出
1
2
 
分析:
  1. 需要两个栈,一个用来存储所有元素main_stack,一个用来存储最小元素min_stack(min_stack的栈顶元素始终是main_stack栈中的最小元素)
  2. push操作,向main_stack栈中添加一个元素;当添加元素小于等于min_stack栈顶元素时或者min_stack为空时,则将该元素也加入min_stack中;
  3. pop操作,main_stack栈顶元素出栈,如果main_stack出栈的元素等于min_stack的栈顶元素,则,min_stack栈顶元素出栈。
  4. getMin操作,返回min_stack的栈顶元素

代码:

#include <iostream>
#include<stack>
using namespace std;
class SStack{
public:
    stack<int> main_stack;
    stack<int> min_stack;

public:
    void push(int a){
        main_stack.push(a);
        if(min_stack.empty()||min_stack.top()>=a){
            min_stack.push(a);
        }
    }
    void pop(){
        if(main_stack.top()==min_stack.top()){
            min_stack.pop();
        }
        main_stack.pop();
    }

    int getMin(){
        if(!min_stack.empty())
            return min_stack.top();
        else{
            return -1;

        }
    }

};

int main()
{
    SStack ss;
    int n;
    cin>>n;
    string op;
    int a;

    for(int i=0;i<n;i++){
        cin>>op;
        if(op=="push"){
            cin>>a;
            ss.push(a);
        }else if(op=="pop"){
            ss.pop();
        }else if(op=="getMin"){
            cout<<ss.getMin()<<endl;
        }

    }
    return 0;
}
View Code

 5、由两个栈组成队列

题目描述

用两个栈实现队列,支持队列的基本操作。

输入描述:

第一行输入一个整数N,表示对队列进行的操作总数。

下面N行每行输入一个字符串S,表示操作的种类。

如果S为"add",则后面还有一个整数X表示向队列尾部加入整数X。

如果S为"poll",则表示弹出队列头部操作。

如果S为"peek",则表示询问当前队列中头部元素是多少。

输出描述:

对于每一个为"peek"的操作,输出一行表示当前队列中头部元素是多少。
示例1

输入

6
add 1
add 2
add 3
peek
poll
peek

输出

1
2

分析:

  1. 栈s1负责进队,栈s2负责出队
  2. add操作,栈s1进栈
  3. poll操作,栈s2出栈;栈s2为空时,先将栈s1的元素依次弹出并压入栈s2,再对栈s2执行弹出操作
  4. peek操作,获取栈s2栈顶的元素;栈s2为空时,先将栈s1的元素依次弹出并压入栈s2,再对栈s2执行返回栈顶元素操作

代码:

#include <iostream>
#include<stack>
using namespace std;
class QQue{
public:
    stack<int> s1;
    stack<int> s2;
public:
    void add(int a){
        s1.push(a);
    }
    void poll(){
        if(s2.empty()){
            while(!s1.empty()){
                s2.push(s1.top());
                s1.pop();
            }
        }
        s2.pop();
    }
    int peek(){
        if(s2.empty()){
            while(!s1.empty()){
                s2.push(s1.top());
                s1.pop();
            }
        }
        if(s2.empty()){
            return -1;
        }
        return s2.top();
    }
};

int main()
{
    int n;
    cin>>n;
    QQue qq;
    string s;
    int a;
    for(int i=0;i<n;i++){
        cin>>s;
        if(s=="add"){
            cin>>a;
            qq.add(a);
        }else if(s=="poll"){
            qq.poll();
        }else if(s=="peek"){
            cout<<qq.peek()<<endl;
        }
    }
    return 0;
}
View Code

6、用递归函数和栈逆序一个栈

题目描述

一个栈依次压入1,2,3,4,5,那么从栈顶到栈底分别为5,4,3,2,1。将这个栈转置后,从栈顶到栈底为1,2,3,4,5,也就是实现栈中元素的逆序,但是只能用递归函数来实现,不能用其他数据结构。

输入描述:

输入数据第一行一个整数N为栈中元素的个数。

接下来一行N个整数X_iXi​表示从栈顶依次到栈底的每个元素。

输出描述:

输出一行表示栈中元素逆序后的每个元素

示例1

输入

5

1 2 3 4 5

输出

5 4 3 2 1

分析:

  1. 首先输入是从栈顶到栈底的元素,那么首先要把这些元素从栈底到栈顶存储
  2. 打印栈时,先打印栈底元素,再打印栈顶元素(递归实现,对于栈中每个元素,先打印其底部的元素,再打印该元素)

代码:

#include <iostream>
#include<stack>
using namespace std;
void f(stack<int> s){
    if(s.empty())
        return;
    else{
        int a=s.top();
        s.pop();
        f(s);
        cout<<a<<" ";
    }
}
int main()
{
    int n;
    cin>>n;
    stack<int> s;
    int A[n];
    for(int i=0;i<n;i++){
        cin>>A[i];
    }
    for(int i=n-1;i>=0;i--){
        s.push(A[i]);
    }
    f(s);
    cout<<endl;
    return 0;
}
View Code







猜你喜欢

转载自www.cnblogs.com/mochensun/p/11896533.html