【面試題】面試題集四

1.【美團】給定一個整型數組arr, 數組長度爲len,現存在a,b知足0<=a<=b<len,求arr[b]-arr[a]的最大值。數組

示例:code

arr:[10, 5]排序

len:2字符串

ans:0get

思路:string

若是對每一個arr[a]比較下標a以後的每一個元素,時間複雜度將達到O(n^2),也是最簡單的方法。若是咱們先對arr進行處理,則能夠轉爲另外一個問題。it

咱們先對arr求差分(後一個元素減去前一個元素),得出一個新的數據diff(diff首個元素爲0,由於diff[0]=arr[0]-arr[0]=0),那麼題目的要求max{arr[b]-arr[a]}則能夠理解爲求解diff數組的最大子數組和。此時,時間複雜度將降爲O(n)。table

好比:class

示例中的arr:[10, 5],diff:[0, -5],則最大子數組和爲0,即max{arr[b]-arr[a]} = 0;test

arr:[1, -2, 3, -4, 10],diff:[0, -3, 5, -7, 14],則max{arr[b]-arr[a]} = arr[4]-arr[3] = 10-(-4) = diff[4] = 14;

arr:[-1, 2, -3, 4, 10],diff:[0, 3, -5, 7, 6],則max{arr[b]-arr[a]}=arr[4]-arr[2] = 10-(-3) = diff[3]+diff[4] = 13;

所以能夠得出以下解答:

 

int maxsum(int a[],int n)      
{    
    int max=a[0];       
    int sum=0;  
    int j;  
    for(j=0;j<n;j++)    
    {    
        if(sum>=0)     
            sum+=a[j];    
        else       
            sum=a[j];  
        if(sum>max)    
            max=sum;    
    }    
    return max;    
} 

int maxdiff(int *array, int len){
	int *diff, i, j;

	diff = (int*)malloc(len*sizeof(int));
	*diff = 0;
	for(i=1; i<len; ++i){
		*(diff+i) = *(array+i)-*(array+i-1);
	}
	return maxsum(diff, len);
}

int array[] = {1,2,3};
#define array_size sizeof(array)/sizeof(int)
int main(void){
	printf("maxdiff of array is:%d\n", maxdiff(array, array_size));
	system("pause");
	return 0;
}

2.【美團】求字典序在字符串s1和字符串s2之間的,長度不超過len的字符串個數,其中s1和s2長度不超過100,len不超過10000000,輸出結果mod 1000007。

示例:

輸入:

s1:ab

s2:ce

len:2

輸出:

56(ac,...az,b,ba,...,bz,c,ca,...,cd)

思路:

字典序顧名思義,表示字典中的排序,好比長度爲1的字符串排序爲a,b,c,...,z,長度爲2的字符串排序爲aa,ab,...,az,ba,...,bz,...,za,...,zz;

固定長度下,好比上面說到的長度爲2的字符串排序,相似於一個26進制('a'->0, 'b'->1...如此類推),但計算26進制的數值須要注意超出存儲空間;,

1)當要求len大於字符串長度時,往字符串末尾補a,並由於a表示數值0,因此並不影響其26進制所計算出來的,好比c_,長度爲2時,補齊爲ca便可;

2)當len小於或者等於s1長度時,好比s1:abc和s2:bcd,這時候是不包含abc的,因此須要減去1,不一樣於len大於字符串長度時,abc_補a時,是包含abca的,因此不須要減1;

3)當len小於s2長度時,好比abc,但要求len爲2,則ab是應該被包含進去的,因此須要加上1.

#define VAL_LIMITED	1000007
static int *base_table;
void base26_cal_init(int len){
	int i,j;

	base_table = (int*)malloc(len*sizeof(int));
	*base_table = 1;
	for(i=1; i<len; ++i){
		*(base_table+i) = *(base_table+i-1)*26;
		*(base_table+i) %= VAL_LIMITED;
	}
}

int base26_cal(char *s, int len){
	int s_len, i; 
	int val;

	s_len = strlen(s);
	for(i=0, val=0; i<s_len&&i<len; ++i){
		val += (*(s+i)-'a')*(*(base_table+len-i-1));
		val %= VAL_LIMITED;
	}

	return val;
}

int number_dict(char *s1, char *s2, int len){
	int s1_len, s2_len;
	int i, j, num;
	int s1_val, s2_val;

	if(strcmp(s2, s1)<0)
		return 0;

	s1_len = strlen(s1)-1;	s2_len = strlen(s2)-1;
	*(s1+s1_len)='\0';	*(s2+s2_len)='\0';
	num = 0;//s2_len-s1_len;
	for(i=len; i>0; --i){
		s1_val = base26_cal(s1, i);
		s2_val = base26_cal(s2, i);
		num += (s2_val-s1_val<0)?s2_val-s1_val+VAL_LIMITED:s2_val-s1_val;
		if(i<=s1_len)
			--num;
		if(i<s2_len)
			++num;
		num %= VAL_LIMITED;
	}
	
	return num;
}

int main(int argc, char *argv[]){
	char test1[101], test2[101];
	int testlen;
	
	while(scanf("%d", &testlen) && testlen>0){
		getchar(); //del enter

		fgets(test1, sizeof(test1), stdin);
		fgets(test2, sizeof(test2), stdin);

		base26_cal_init(testlen);
		printf("num of string among \"%s\" and \"%s\" is:%d\n", test1, test2, number_dict(test1, test2, testlen));
		free(base_table);
	}

	system("pause");
	return 0;
}
相關文章
相關標籤/搜索