两道简单的笔试题

/***********************Update**************************/
第一道题: O(N) 的解法:

int findMaxDifference_2(int *arr,int len){
    int num=0;
    for(int i=0;i<len;i++)
        if(arr[i+1]-arr[i]>0 && arr[i+1]-arr[i]>num)
            num=arr[i+1]-arr[i];
    return num;
}

今天做了一个公司的笔试题,不过其实第二道我之前在编程之美上就看到过,不过考试时没写出来。第一道题如下:
有一个数组arr,长度为len;现有a,b。0=<a<=b<=len-1 请编写一个程序,找出arr[b]-arr[a]的最大值。
举例:

[1015]

输出:0
这个我当时第一感觉就是有点类似最大子数组之和的。不过很明显有一个暴力的 O(n2) 的解法,不过感觉不对劲啊。复杂度有点高,但是当时也没有想起来优化的办法。就试了一下提交了。最后这道题竟然过了。
我的解法如下,大家如果找到了 O(N) 复杂度的,可以分享下。

#include <stdio.h>
int findMaxDifference(int *arr, int len) {
   int result=0,temp=0;
   for(int i=0;i<len;i++)
    for(int j=i;j<len;j++){
        if((temp=arr[j]-arr[i])>0 && temp > result)
            result = temp;
    }
    return result;
}
int main(int argc,char **argv){
    int arr[3]={10,5};
    printf("The MaxDifference is : %d\n",findMaxDifference(arr,2));
}

第二个问题:
现有两个字符串s1 s2。有2种操作:左移,右移。
左移:将字符串第一个字符移到最后
右移:将字符串最后一个字符移动到第一位
举例:

s1 = "abcd"
s2 = "bcda"

则s2右移一位之后便于s1相等。如果是左移,则需要:

cdab->dabc->abcd

三次运算
问题就是:给定两个字符串,求最少移动多少次可使得两个字符串相等。如果不能找到一个解,返回-1
虽然之前看过了,不过第一眼看到时以为这是一个动态规划求最优解。后来一分析:虽然题意上说有左移和右移两种选择,可能有人会以为先左移,再右移这样可能会出现最优解。仔细一想你就发现,实际上只有两个选择:循环左移,循环右移。
到这里,就可以写代码了。当然,还有第二种以时间换空间的解,不过你看编程之美去吧。我有空可能会写。

#include <cstdio>
#include <string.h>

int ifEqual(char *s1,char *s2,int len){
    for(int i=0;i != len ; i++)
        if(s1[i]!=s2[i])
            return 0;
    return 1;
}

void shiftRight(char *src,int len){
    char temp=src[len-1];
    for(int i=len-2;i>=0;i--)
        src[i+1]=src[i];
    src[0]=temp;
}
void shiftLeft(char *src,int len){
    char temp=*src;
    for(int i=1;i<len;i++)
        src[i-1]=src[i];
    src[len-1]=temp;
}
int print(bool flag1,bool flag2,int L,int R){
    if(!flag1 && !flag2)
        return -1;
    else
        return L<R? L : R;
}
int distance(char *s1, char *s2) {
    int len1 = strlen(s1);
    int len2 = strlen(s2);
    char temp[len1+1];
    bool flag1=false,flag2=false;
    strcpy(temp,s2);
    if(len1 != len2)
        return -1;
    int leftCount=0,rightCount=0;
    //左移
    for(int i=0; i<len1;i++){
        shiftLeft(s2,len2);
        leftCount++;
        if(flag1=ifEqual(s1,s2,len1))
            break;
    }
    if(leftCount==len1-1 && !flag1); //左移无解
    //右移
    strcpy(s2,temp);
    for(int i=0; i<len1;i++){
       shiftRight(s2,len2);
       rightCount++;
       if(flag2=ifEqual(s1,s2,len1))
         break;
    }
    if(rightCount==len1-1 && !flag2); //右移无解
    //return
    return print(flag1,flag2,leftCount,rightCount);
}
int main(int argc,char **argv){
    char s1[]="abcd";
    char s2[]="bdaa";
    int result=distance(s1,s2);
    printf("result:%d\n",result);
    return 0;
}

以上

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值