二刷《剑指OFFER》笔记

特别注意:函数输入是否有效,例如空指针,然后引用下标时注意是否越界

 

可重复全排列

#include<bits/stdc++.h>

using namespace std;

void prt(char *s,int n){

    int i=0;

    while(s[i]=='0')i++;

    for(;i<n;i++)cout<<s[i];

    cout<<endl;

}

void dfs(char* s,int n,int p){//

    if(p==n){

        prt(s,n);

        return;

    }

    for(char c='0';c<='9';c++){

        s[p]=c;

        dfs(s,n,p+1);

    }

}

int main(){

    int n;cin>>n;

    char s[n+1];

    memset(s,'0',n);

    s[n]='\0';

    dfs(s,n,0);

    return 0;

}

 

不重复全排列

#include<bits/stdc++.h>

using namespace std;

void dfs(string s,int n,int p){

    if(p==n)cout<<s<<endl;

    for(int i=p;i<n;i++){

        swap(s[p],s[i]);

        dfs(s,n,p+1);

    }

}

int main(){

    string s;cin>>s;

    dfs(s,s.size(),0);

    return 0;

}

 

模板串匹配

#include<bits/stdc++.h>

using namespace std;

bool dfs(char* s,int i,char* t,int j){

    if(s[i]=='\0'){//s到尽头了则t必须也到尽头或下一个是*

        if(t[j]=='\0')return true;

        if(t[j+1]='*')return dfs(s,i,t,j+2);

        return false;

    }

    if(t[j+1]=='*'){//c对c*

        if(s[i]!=t[j])return dfs(s,i,t,j+2);

        return dfs(s,i+1,t,j)||dfs(s,i,t,j+2)||dfs(s,i+1,t,j+2);

    }else{//c对.或c对c

        if(s[i]==t[j])return dfs(s,i+1,t,j+1);

        if(t[j]=='.')return dfs(s,i+1,t,j+1);

        return false;

    }

}

int main(){//已知t串不存在.*与**

    char s[103],t[103];cin>>s;cin>>t;

    if(dfs(s,0,t,0))cout<<"YES"<<endl;

    else cout<<"NO"<<endl;

    return 0;

}

 

前缀中缀求二叉树

#include<bits/stdc++.h>

using namespace std;

struct node{

    char val;

    struct node* lft;

    struct node* rht;

}*root;

node* dfs(string s,int s1,int s2,string t,int t1,int t2){

    if(s1>s2)return NULL;

    node* p=new node;

    p->val=s[s1];

    int i;for(i=t1;i<=t2;i++)if(t[i]==s[s1])break;

    p->lft=dfs(s,s1+1,s1+i-t1,t,t1,i-1);

    p->rht=dfs(s,s1+i-t1+1,s2,t,i+1,t2);

    return p;

}

void prt(node* p){

    if(p==NULL)return ;

    prt(p->lft);

    prt(p->rht);

    cout<<p->val;//后序遍历

}

int main(){

    int n;cin>>n;

    string s;cin>>s;

    string t;cin>>t;

    root=dfs(s,0,n-1,t,0,n-1);

    prt(root);

    return 0;

}

 

不等长数组求中位数

写法一

#include<bits/stdc++.h>

using namespace std;

int A[103],B[103];

int findkth(int A[], int m, int B[], int n, int k){

       if(m > n)return findkth(B, n, A, m, k);

       if(m ==0)return B[k-1];

       if(k ==1)return A[0]<B[0]?A[0]:B[0];

       int pa = k/2<m?k/2:m,pb = k - pa; //前k个数有pa个数在A中,有k-pa个数在B中

       if(A[pa-1] < B[pb-1])  return findkth(A+pa,m-pa,B,n,k-pa); //A切去一半

       if(A[pa-1] > B[pb-1])  return findkth(A,m,B+pb,n-pb,k-pb); //B切去一部分

       else                   return A[pa-1];

}

double findMedianSortedArrays(int A[], int m, int B[], int n){

       if((m+n)%2)return findkth(A,m,B,n,(m+n)/2+1);

       else return ((double)findkth(A,m,B,n,(m+n)/2)+findkth(A,m,B,n,(m+n)/2+1))/2;

}

int main(){

    int m,n;cin>>m>>n;

    for(int i=0;i<m;i++)cin>>A[i];

    for(int i=0;i<n;i++)cin>>B[i];

    cout<<findMedianSortedArrays(A,m,B,n)<<endl;

    return 0;

}

写法二

int find_median(int *A,int *B,int m,int n,int s,int t){

    int p=(s+t)/2,c=(m+n-1)/2;/* 有多少个数小于下中位数 */

    if(s>t)return find_median(B,A,n,m,0,n-1);/* 如果下中位数不在A中,就从数组B找 */

    else if(A[p]>=B[c-p-1]&&A[p]<=B[c-p])return A[p];/* 数组A中有p个数小于A[p], 当且进当数组B中有c-p个数小于A[p], A[p]才是中位数 */

    else if(A[p]<B[c-p-1])return find_median(A,B,m,n,p+1,t);/* A[p]太小了,从数组A中找一个更大的数尝试 */

    else return find_median(A,B,m,n,s,p-1);/* A[p]太大了,从数组A中找一个更小的数尝试 */

}

int main(){

    int A[]={1,3,5,7,9};

    int B[]={2,4,6,8,10};

    int m = sizeof(A)/sizeof(int);

    int n = sizeof(B)/sizeof(int);

    printf("%d\n", find_median(A, B, m, n, 0, m-1));/* 从数组A和B中找下中位数 */

    return 0;

}

前中缀变后缀

#include <bits/stdc++.h>
using namespace std;
char pre[103],in[103],suf[103];
int id=0;
void vis(int s1,int s2,int t1,int t2){
    if(s1>s2||t1>t2)return ;
    int mid=t1;
    while(pre[s1]!=in[mid])mid++;
    vis(s1+1,s1+mid-t1,t1,mid-1);
    vis(s1+mid-t1+1,s2,mid+1,t2);
    suf[id++]=pre[s1];
}
int main(){
    gets(pre);gets(in);
    int len=strlen(pre);
    vis(0,len-1,0,len-1);
    suf[id]='\0';
    cout<<suf<<endl;
    return 0;
}
/*
in
1245367
4251637
out
4526731
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值