经典的面试题

 

题目1

输入一个整形数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值。要求时间复杂度为O(n)。

例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,因此输出为该子数组的和18。

/// <summary>      
  /// 获得数组最大子数组的和       
 /// </summary>       
 /// <param name="intArr">整形 数组</param>  
      /// <returns>最大子数组的和</returns>   
     public static int GetMaxChild(int[] intArr)        
 {         
   if (intArr == null || intArr.Length == 0)     
       {             
   throw new ArgumentException("传入没有内容的数组!");       
     }            
int result = 0; // 最大和     
       int tempSum = 0; // 累加和   
         int maxNegative = intArr[0]; // 数组最大值  
          for (int i = 0; i < intArr.Length; i++)         
   {               
 if (tempSum <= 0)            
    {                 
   tempSum = intArr[i]; // 始终保持为正,左边如果为负数则抛弃      
          }            
    else              
  {                   
 tempSum += intArr[i];     
           }             
   if (tempSum > result)     
           {                
    result = tempSum;   // 始终保持最大的和   
             }               
 if (intArr[i] > maxNegative)     
           {                   
 maxNegative = intArr[i];            
    }         
   }           
 if (maxNegative < 0)        
    {            
    return maxNegative; // 所有数都为负数,只返回最大的一个数     
       }           
 return result;      
  }

 

题目二、

 输入n个整数,输出其中最小的k个。

例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4。

 

/// <summary>
/// 输入n个整数,输出其中最小的k个。
/// </summary>
/// <param name="array"></param>
/// <param name="FindCount"></param>
public static List<int> GetMinCountNumber(int[] array, int FindCount)
{
if (FindCount <= 0)
{
    
throw new ArgumentException("输出其中最小的个数应大于1!", "错误参数:FindCount");
    }
   
if (array == null || array.Length < FindCount)
{
throw new ArgumentException("数组不能为空或长度应大于输出个数!", "错误参数:array");
}
#region 排序
int temp; //临时变量,保存最大,小值
for (int j = 0; j < array.Length; j++)
{
    
for (int i = 0; i < array.Length - j - 1; i++)
{
  
if (array[i] > array[i + 1]) // 如果 array[i] > array[i+1]
       {
      temp
= array[i];
array[i]
= array[i + 1];
    array[i
+ 1] = temp;
      }
    }
  }
#endregion
//返回最小的k个
List<int> intList = new List<int>();
for (int i = 0; i < FindCount; i++)
{
intList.Add(array[i]);
}
return intList;
}

题目三、

输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。句子中单词以空格符隔开。为简单起见,标点符号和普通字母一样处理。

例如输入“I am a student.”,则输出“student. a am I”。

思路:把字符串按空格分割成数组,然后倒序拼接输出

但是:出题人的意图是不让你用string里的方法分割拼接。最后我只能自己想办法反转了,如果不用string里的方法有点小复杂!

 

/// <summary>        
///反转字符串顺序 
/// </summary>
 /// <param name="str"></param>        
/// <returns></returns>        
public static string GetStrReverse(string str)        
{            
if (str == null || str == string.Empty)           
 {               
 throw new ArgumentException("请输入需要反转的字符!", "错误参数:str");            
}            
//全部反转           
 StringBuilder currentStr = new StringBuilder(str.Length);            
for (int i = str.Length - 1; i >= 0; i--)            
{                
currentStr.Append(str[i]);           
 }            
#region 单词顺序复原            
char tempChar;           
 int indexBegin = 0;            
int indexEnd = 0;            
for (int i = 0; i < currentStr.Length; i++)           
 {               
 if (currentStr[i] == ' ')                
{                   
 indexEnd = i - 1;                   
 while (indexBegin < indexEnd)                   
 {                       
 tempChar = currentStr[indexBegin];                        
currentStr[indexBegin] = currentStr[indexEnd];                        
currentStr[indexEnd] = tempChar;                        
indexBegin++;                       
 indexEnd--;                   
 }                   
 indexBegin = i + 1;//跳过空格                 
}              
  else if (currentStr[i] == '!' || currentStr[i] == ',' ||
 currentStr[i] == '.' || currentStr[i] == ';' || currentStr[i] == '?')                {                  
  indexBegin = i + 1; //跳过标点符号                
 }            
}           
 #endregion          
  return currentStr.ToString(); 
 }

 

题目四、

求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)。

解:这个好像有点复杂,好像说的什么都不能用一样,这道题想了蛮久但代码很简单!

 

/// <summary>       
 ///返回阶加结果(内部没有验证输入参数)        
/// </summary>        
/// <param name="n">阶加长度</param>        
/// <param name="sum">返回结果</param>        
/// <returns></returns>        
public static bool GetIntSum(int n, ref int sum)       
 {            
  sum += n;          
  return (n - 1 <= 0) || (GetIntSum(n - 1, ref sum));   
 }

 

题目五、

输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。要求时间复杂度是O(n)。如果有多对数字的和等于输入的数字,输出任意一对即可。

思路:找到数组的第一个数字和最后一个数字。当两个数字的和大于输入的数字时,把较大的数字往前移动;当两个数字的和小于数字时,把较小的数字往后移动;当相等时,输出等式

/// <summary>
/// 在排序数组中查找和为给定值的两个数字
/// </summary>
/// <param name="array">输入数组(要求已排序)</param>
/// <param name="sum">指定和</param>
public static Dictionary<int, int> FindTwoNumbersWithSum(int[] array, int sum)
{
if (array == null || array.Length <= 0)
{
throw new ArgumentException("数组不能为空!", "错误参数:array");
}
if (sum < 1)
{
throw new ArgumentException("请输入一个大于0的数", "错误参数:sum");
}

Dictionary
<int, int> dicIntArray = new Dictionary<int, int>();
 int indexBegin = 0;
int indexEnd = array.Length - 1;
while (indexEnd > indexBegin)
{
int currentSum = array[indexEnd] + array[indexBegin];
if (currentSum == sum)
{
dicIntArray.Add(array[indexBegin], array[indexEnd]);
break;
}
else if (currentSum > sum)
indexEnd
--;
else
indexBegin
++;
}
return dicIntArray;
  
}
posted @ 2011-06-22 14:51  wumc  阅读(153)  评论(0)    收藏  举报