【算法】各大公司笔试题目之数组相关笔试题

对于数组中数字的各种操作引发的笔试题目也是各种各样。本篇文章就对数组中和数字相关的笔试算法题目进行总结。

一:编程之美 求一个数组能组成的最大的数

给定只包含正数的数组,给出一个方法,将数组中的数拼接起来,得到的数,是最大的。 例如: [4, 94, 9, 14, 1] 拼接之后,所得最大数为:9944141

思路其实很简单,就是按照数的大小排序,大的排到高位,小的排到低位,然后依次输出排好序的数字,这个时候最后的结果肯定是最大的。比如对于数组[1,2,3,4,5],从大到小排序后结果为[5,4,3,2,1],所以最后可以组成的最大结果就是54321。

但是,上面数组中所有元素的位数都是相同的,都是一位。当遇到位数不同的时候就需要稍微额外处理一下。比如第一个数组中的9,94两个数字,那谁应该排在前面那。遇到这种情况就使用虚拟填充的做法,填充到两个两个数的位数相同,然后再做比较。对于9,94来说,因为9只有一位,而94是两位,那么就把9填充为99,这个时候比较99与94的大小,结果就是实际数字9,94的大小了。在填充的时候,填充的数字为位数少的数字的本身。还是上面数组对于14与1比较,最后填充后的结果就是14与11的比较,可以看出14大于11,所以14要排在1的前面。

#include <stdio.h>
#include <stdlib.h>
/*
  Name: 
  Copyright: 
  Author: 
  Date: 20/07/13 11:51
  Description: 数组中的数拼接起来,得到的数是最大
*/
int comp(const void *first, const void *second){
	 int a = *(int *) first;
	 int b = *(int *) second;
	 char a_str[3];
	 char b_str[3];
	 itoa(a, a_str, 10);
	 itoa(b, b_str, 10);
	 if(a_str[0] == b_str[0]){
          //进行虚拟填充,每次比较位数少那个数字的第一位 ,我默认数组每个元素最大为三位数
	 	  for(int i = 1; i < 3; i ++){
		  	    if(a_str[1] > b_str[1]){
					  if(b_str[1] != ' '){
		                    return true;
					  }else{
					  	    if(a_str[1] > b_str[0]){
								   return true;
				            }	
				            return false;
					  }
			   		  return false;
	            }else{
					  if(a_str[1] != ' '){
		                    return true;
					  }else{
					  	    if(a_str[0] > b_str[1]){
								   return true;
				            }	
				            return false;
					  }
			    }
          }
     }else{
                if(a_str[0] > b_str[0]){
		   		      return true;
		         }
		         return false;
     }
	 
}
void sortArray(int *array, int length){
	 for(int i = length - 1; i >= 0; i --){
	 	   printf("%d ", array[i]);
     }
      printf("\n");
	 qsort(array, length, sizeof(int), comp);
	 for(int i = length - 1; i >= 0; i --){
	 	   printf("%d", array[i]);
     }
}

void max(int *array, const int length){
	  if(array == 0){
	  	   return;
      }
      sortArray(array, length);
      
}

main(){
      int array[] = {4, 94, 9, 14, 1};
	  max(array, 5); 
      system("pause"); 
}


二:编程之美 求一个数组最大和(微软笔试题目)

这个题目应该还是比较经典的,很多公司都考试过。题目大意是给出一个数组,让你求该数组能组成的最大的和是多少,并打印出组成最大和的子数组。

该题目可以利用暴力法,两个for循环嵌套,挨个寻找最大的值,这是O(n^2)的复杂度。优化后的算法是利用动态规划的思想进行求和计算。

主要思想就是声明最大和sum为0,从末尾朝前开始遍历,并挨个相加。对于相加后的值tmp与sum比较,如果大于sum则更新sum的值;如果小于sum但是大于0,则tmp保持不变继续朝前遍历;如果小于sum而且小于0,那么tmp置0,sum不变,继续朝前遍历。算法结束


三:编程之美 求两个数组的和为某个数值(微软笔试题目)

解法1:肯定是可以通过暴力去两次遍历解决的。第一层遍历选择一个数,第二层遍历看当前的数值和外层循环的数值的和是否为给定值。复杂度为n^2。

解法2:可以先通过排序,让数组变成有序的,然后外层一个for循环获取一数值current,通过result = sum-current得到另一个值,然后通过二分查找检查数组中是否含有result。复杂度为n*logN

四:编程之美 求三个数的和为某个数组(雅虎笔试题目)

这个题目是今年的雅虎笔试题目。意思是给出两个数组A,B,让你在某个数组中找出一个,另一个数组中找出者两个,让三个数值的和为给定的sum值。

其实这个题目可以拆分成两个过程:

第一步在数组A中选择一个数值current,然后result = sum - current,再去数组B中检查是否有两个值的和为result,这就回到了上一个题目

第二步在数组B中选择一个数字,和第一步做相同的操作。

复杂度为n^2*logN。针对此题目有好的想法,还请提出。

五:编程之美 求一个N个元素的数组中N-1个的最大乘积。

算法思想是优先求出数组中所有值的乘积,然后根据乘积的不同情况进行不同分析。对于所有数的乘积,其结果只有三种情况大于0、等于0和小于0。所以我们也可以针对这三种情况做不同的分析。

#include <iostream>
#include <stdlib.h>
#include <limits>
using namespace std;
const int LENGTH = 10;
int max1(const int array[]){
	  int sum = 1;
	  for(int i = 0;i < LENGTH; i++){
	  		sum = sum * array[i];
      }

      if(sum == 0){
  		    int zero_num = 0;
	  		for(int i = 0;i < LENGTH; i++){
	  				if(array[i] == 0) {
							zero_num ++;
					}
      		}	   
      		if(zero_num >1){
					sum = 0;
			}else{
				  	sum = 1;
				  	for(int i = 0; i < LENGTH; i++){
	  						if(array[i] != 0) {
								  sum = sum	* array[i];
							}
      				}
      				if(sum < 0) sum = 0;
	        }
	  }else if(sum < 0){
	  		int min = INT_MAX;
	  		for(int i = 0;i < LENGTH; i++){
	  				if(abs(array[i]) <= min){
						 	min = array[i];
				    }
      		}	
      		sum = sum / min;	
	  }else{
	  		int min = INT_MAX, max = 0;
			for(int i = 0;i < LENGTH; i++){
	  				if(array[i] >0 && array[i] <= min){
						 	min = array[i];
				    }
				    if(abs(array[i]) > max){
							max = array[i];				 
		            }
      		}
			if(min == INT_MAX){
				 sum = sum / max;
		    }else{
			     sum = sum / min;	  
	        }
	  }
	  return sum;
}
main(){
      int array[LENGTH];
      for(int i = 0;i < LENGTH; i++){
	  		cin >> array[i];
      }
	  for(int i = 0;i < LENGTH; i++){
	  		cout << array[i] << " ";
      }
      int max = max1(array);
      cout << endl;
      cout << "max:" << max;
      system("pause"); 
}



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值