5道经典的程序题

昨天下午在公司没事,动手写了几道面试题,我也不是闲的发慌,就是感觉每天写业务方面的代码写长了,思维不是很局限,想做下算法题活跃下思维!  欢迎发表意见和拍砖!

题目1

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

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

 

ContractedBlock.gif ExpandedBlockStart.gif View Code
/// <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;
}

题目2

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

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

解:

 

ContractedBlock.gif ExpandedBlockStart.gif View Code
/// <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;
}

 

题目3

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

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

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

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

ContractedBlock.gif ExpandedBlockStart.gif View Code
/// <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();
}

题目4

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

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

 

ContractedBlock.gif ExpandedBlockStart.gif View Code
/// <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));
}

 

 

 

题目5

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

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

ContractedBlock.gif ExpandedBlockStart.gif View Code
/// <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;

}

转载于:https://www.cnblogs.com/ValiantShield/archive/2011/06/22/2086639.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值