几道算法题目
题目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>publicstaticint GetMaxChild(int[] intArr) { if (intArr ==null|| intArr.Length ==0) { thrownew 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; }
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。
解:
///<summary>/// 输入n个整数,输出其中最小的k个。 ///</summary>///<param name="array"></param>///<param name="FindCount"></param>publicstatic List<int> GetMinCountNumber(int[] array, int FindCount) {
if (FindCount <=0) { thrownew ArgumentException("输出其中最小的个数应大于1!", "错误参数:FindCount"); }
if (array ==null|| array.Length < FindCount) { thrownew 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; }
if (FindCount <=0) { thrownew ArgumentException("输出其中最小的个数应大于1!", "错误参数:FindCount"); }
if (array ==null|| array.Length < FindCount) { thrownew 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里的方法有点小复杂!
///<summary>///反转字符串顺序 ///</summary>///<param name="str"></param>///<returns></returns>publicstaticstring GetStrReverse(string str) { if (str ==null|| str ==string.Empty) { thrownew 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;//跳过空格 }
elseif (currentStr[i] =='!'|| currentStr[i] ==','|| currentStr[i] =='.'|| currentStr[i] ==';'|| currentStr[i] =='?') {
indexBegin = i +1; //跳过标点符号 }
}
#endregion
return currentStr.ToString(); }
//全部反转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;//跳过空格 }
elseif (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)。
解:这个好像有点复杂,好像说的什么都不能用一样,这道题想了蛮久但代码很简单!
///<summary>///返回阶加结果(内部没有验证输入参数) ///</summary>///<param name="n">阶加长度</param>///<param name="sum">返回结果</param>///<returns></returns>publicstaticbool GetIntSum(int n, refint sum) { sum += n; return (n -1<=0) || (GetIntSum(n -1, ref sum)); }
题目5
输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。要求时间复杂度是O(n)。如果有多对数字的和等于输入的数字,输出任意一对即可。
思路:找到数组的第一个数字和最后一个数字。当两个数字的和大于输入的数字时,把较大的数字往前移动;当两个数字的和小于数字时,把较小的数字往后移动;当相等时,输出等式
///<summary>/// 在排序数组中查找和为给定值的两个数字 ///</summary>///<param name="array">输入数组(要求已排序)</param>///<param name="sum">指定和</param>publicstatic Dictionary<int, int> FindTwoNumbersWithSum(int[] array, int sum) { if (array ==null|| array.Length <=0) { thrownew ArgumentException("数组不能为空!", "错误参数:array"); }
if (sum <1) { thrownew 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; } elseif (currentSum > sum) indexEnd--; else indexBegin++; }
return dicIntArray;
}
if (sum <1) { thrownew 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; } elseif (currentSum > sum) indexEnd--; else indexBegin++; }
return dicIntArray;
}