笔试题集锦(编程题)

1.已知数组a前半部分a[0,mid - 1],后半部分a[mid,num-1],现前半部分和后半部分均已排好序。要求:实现a数组的从小到大排序。空间复杂度为O(1).

void MergeSort(int *v, const int len, const int mid)  
{    
    int i, temp;  
    int left = 0, right = mid;  
  
    while (left < right && right < len)  
    {  
        while (v[left] < v[right]) {  
            ++ left;  
        }   
  
        temp = v[right];  
        for(i = right; i > left ; -- i) {  
            v[i] = v[i-1];  
        }  
        v[left] = temp;  
  
        //move the current right postion  
        ++ right;     
    }  
  
}  
//int arry[]={1,3,5,7,9,3,4,6,8};  
//int arry[]={1,3,5,7,9,7,8,9,9,11};  
//int arry[] = {0,2,4,6,8,8,9,9,1000,1,3,5,7,10,11,12,14,16,18,20,21,23,25,45,68};     
  int v[] = {100,1,3,5,7,10,11,12,14,16,18,20,21,23,25,45,68};

2.给一个字符串和一个字符集,求该字符串包含字符集的子串

给出一个字符串,及一个字符集,求该字符串包含所有字符集的最短子串

思路:每次找到一个在字符集中出现的字符,都判断该字符是否是第一次出现,如果是第一次出现,直接记录其下标,如果不是第一次出现,看下它是否和index指向的那个字符是否为相同字符,如果是相同字符,需要更新index找到它后面的第一个已经出现的字符,如果不是index的指向,只需要更新他的下标即可,index中保留的始终是满足都出现的最大下标,这样使得找到的长度是最短的。

时间复杂度O(n)

#include <iostream>
using namespace std;
const int N=128;
const int INF=10000;
const int MAXLEN=100;
//找到所有已经出现的最小下标
int getMinIdx(char *s)
{
    int rs=-1;
    for(int i=0;i<N;i++)
    {
        if(s[i]>=0)
        {
            if(rs == -1)
                rs=s[i];
            else if(rs>s[i])
                rs=s[i];
        }
    }
    return rs;
}
void findMinSubStr(char *str,char *set)
{
    int i,minIdx,subIndex,minLen,num;
    minIdx=-1;
    minLen=INF;
    subIndex=-1;
    num=0;
    char idx[N],result[MAXLEN];
    for(i=0;i<N;i++)
        idx[i]=-2; //初始化符号及标记数组
    for(i=0;‘\0‘ != set[i];i++)
    {
        idx[set[i]]=-1;
        num++; //统计字符集大小
    }
    cout<<num<<endl;
    for(i=0;‘\0‘ != str[i];i++)
    {
        if(idx[str[i]] > -2)//判断字符串中的字符是否出现在字符集中
        {
            if(-1 == idx[str[i]]) //判断是否第一次出现
            {
                idx[str[i]]=i;
                num--;
                if(-1 == minIdx)
                    minIdx=i; //minIdx指向字串的开始下标
            }
            else if(minIdx == idx[str[i]]) 
//如果当前字符与子串第一个字符相同则更新子串第一个字符为下一个已经出现的字符
//看下它是否和index指向的那个字符是否为相同字符,如果是相同字符,需要更新index找到它后面的第一个已经出现的字符
            {
                idx[str[i]]=i;
                minIdx=getMinIdx(idx);//返回所有已经出现字符的最小下标
            }
            else //若都不是直接更新下标到idx
            {
                idx[str[i]]=i;
            }
        }
        if(!num)
        {
            if(minLen > (i-minIdx+1))
            {
                subIndex=minIdx;
                minLen=i-minIdx+1;
            }
        }
        cout<<subIndex<<‘ ‘<<minIdx<<‘ ‘<<minLen<<endl;
    }
    for(i=0;i<minLen;i++)
    {
        result[i]=str[i+subIndex];
    }
    result[i]=‘\0‘;
    cout<<"包含字符集中所有字符的最短子串为:";
    cout<<result<<endl;
}
int main()
{
    char str[MAXLEN],set[MAXLEN];
    memset(str,‘\0‘,sizeof(MAXLEN));
    memset(set,‘\0‘,sizeof(MAXLEN));
    cout<<"输入字符串和字符集:"<<endl;
    cin>>str>>set;
    findMinSubStr(str,set);
    return 0;
}

二分法的递归与非递归

递归:

void Search(int p[],int low,int height,int key)  
{  
    int middle=(low+height)/2;  
    if(low>height)  
    {  
        printf("没有该数!");  
        return;  
    }  
    if(p[middle]==key)  
    {  
        printf("%d\n",middle);  
        return;  
    }  
    else if(p[middle]>key)  
    {  
         Search(p,low,middle-1,key);  
    }  
    else if(p[middle]<key)  
    {  
         Search(p,middle+1,height,key);  
    }  
} 
int main()  
{  
    int p[5]={1,2,3,4,5};  
    Search(p,0,4,4);  
    return 0;  
}

非递归:

int Search(int* arr, int size,int key)
{
	if (arr == NULL || size <= 0)
		return;
	int mid = 0;
	int begin = 0;
	int end = size - 1;
	while (begin <= end)
	{
		mid = begin + ((end - begin) >> 2);
		if (arr[mid] == key)
			return mid;
		else if (arr[mid] > key)
		{
			end = mid - 1;
		}
		else
		{
			begin = mid + 1;
		}
	}
	return -1;
}
题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增的排序的数组的一个旋转,输出旋转数组的最小元素。例如输入{1,2,3,4,5}的一个旋转为{3,4,5,1,2},该数组的最小值为1。
public class Solution {
    public int minNumberInRotateArray(int [] array) {
        int low = 0 ; int high = array.length - 1;   
        while(low < high){
            int mid = low + (high - low) / 2;        
            if(array[mid] > array[high]){
                low = mid + 1;
            }else if(array[mid] == array[high]){
                high = high - 1;
            }else{
                high = mid;
            }   
        }
        return array[low];
    }
}
时间: 2024-08-24 14:03:53

笔试题集锦(编程题)的相关文章

C笔试题之编程题四

13.一个8*8的矩阵内存储1-9的数字,找到一个4*4的方阵使其和最小. 思路:穷举法 1 #include <stdio.h> 2 3 #define uchar unsigned char 4 5 int main(void) 6 { 7 uchar square[8][8] = { 8 { 1, 4, 6, 8, 4, 9, 0, 7 }, 9 { 2, 6, 3, 7, 2, 1, 8, 7 }, 10 { 1, 6, 9, 8, 5, 3, 2, 8 }, 11 { 4, 5, 7

笔试题集锦(智力题)

一.简答题 1. 动态链接库和静态链接库的优缺点 2. 轮询任务调度和可抢占式调度有什么区别? 3. 列出数据库中常用的锁及其应用场景 二.算法设计题 1. 给定N是一个正整数,求比N大的最小"不重复数",这里的不重复是指没有两个相等的相邻位,如1102中的11是相等的两个相邻位故不是不重复数,而12301是不重复数. 2. 设N是一个大整数,求长度为N的字符串的最长回文子串. 3. 坐标轴上从左到右依次的点为a[0].a[1].a[2]--a[n-1],设一根木棒的长度为L,求L最多

2018春招-今日头条笔试题-第三题(python)

题目描述:2018春招-今日头条笔试题5题(后附大佬答案-c++版) 解题思路: 本题的做法最重要的应该是如何拼出'1234567890',对于输入表达试获得对应的结果利用python内置函数eval()即可以实现.利用5个字符串来表达'1234567890',如下(为了好看,里面加了tab空格符) '66666 ....6 66666 66666 6...6 66666 66666 66666 66666 66666''6...6 ....6 ....6 ....6 6...6 6.... 6

笔试题集锦

1.C++有哪些数据类型?为什么long和int都是4字节? C++的数据类型有字符型(char).布尔型(bool).短整型(short).整型(int).长整型(long).浮点型(float).双精度型(double)等类型 首先并不是所有的long和int都是4字节的,在C++中规定int的长度是大于等于short的长度,小于等于long的长度,并且要大于2字节,在16位CPU以及单片机中,int是2字节的,而在32位CPU及以上的CPU中int是4字节的: 在C++中long的长度应该

Java笔试题-线程编程方面

Ja 线程编程方面 60.java中有几种方法可以实现一个线程?用什么关键字修饰同步方法?stop()和suspend()方法为何不推荐使用? 答:有两种实现方法,分别是继承Thread类与实现Runnable接口 用synchronized关键字修饰同步方法 反对使用stop(),是因为它不安全.它会解除由线程获取的所有锁定,而且如果对象处于一种不连贯状态,那么其他线程能在那种状态下检查和修改它们.结果很难检查出真正的问题所在.suspend()方法容易发生死锁.调用suspend()的时候,

一道 google曾出过的笔试题:编程实现对数学一元多项式的相加和相乘操作(1)

数学中一元n次多项式可表示成如下的形式: Pn(x)=p0+p1x+p2x^2+…+pnx^n     (最多有 n+1 项,n +1 个系数唯一确定她) (1)请设计一套接口用以表示和操作一元多项式 (2)根据上述设计实现一元n次多项式的加法运算 (3)根据上述设计实现一元n次多项式的乘法运算 分析:  题目大概意思: 数学里常见的一元 n 次表达式,设计出加减乘除的函数(方法),同时提供对外接口,把内部实现封装起来,而 n 的大小没有指定. 问题的本质: 就是一系列的单个未知数 x,指数和系

阿里巴巴 2015年校招 笔试题(附加题)

PS: 前面的选择题:考了各种逻辑推理题.概率题···醉了··· (1)给定一个query和一个text,均由小写字母组成.要求在text中找出以同样的顺序连续出现在query中的最长连续字母序列的长度.例如, query为“acbac”,text为“acaccbabb”,那么text中的“cba”为最长的连续出现在query中的字母序列,因此,返回结果 应该为其长度3.请注意程序效率. (2)写一个函数,输入一个二叉树,树中每个节点存放了一个整数值,函数返回这棵二叉树中相差最大的两个节点间的差

fpga笔试题集锦(血的教训)

1.名词解释: FPGA:现场可编程门阵列,一般工艺SRAM(易失性),所以要外挂配置芯片. CPLD:复杂可编程逻辑器件,一般工艺Flash(不易失). ASIC:专用集成电路 SOC:片上系统 SOPC:片上可编程系统 2.Verilog语法类: ①Verilog两大数据类型:一类是线网类型,另一类是寄存器类型. 线网类型表示硬件电路元件之间实际存在的物理连线,有很多种:wire.tri.wor等等,当然日常使用wire最多,其他的都没遇到过. 寄存器类型表示一个抽象的数据存储单元,只能在i

笔试题整理 第二题

班上同学聚餐吃火锅,一锅煮了m(1<=m<=50)个鱼丸和n(1<=n<=50)个肉丸,现欲将m个鱼丸和n个肉丸分到k(1<=k<=50)个碗中,允许有空碗,鱼丸和肉丸不允许混在同一个碗里,问共有多少种装法? 假设碗足够大,能够装50个鱼丸和50个肉丸,并且碗没有任何区别.因此当m等于n等于1,k等于3时,有一种装法,因为110,101,011被看做同一种方法. #include <iostream> #include <vector> #inc