题目:二维数组中的查找
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
思路:找出二维数组的规律,从左下到右上查找最快。
提高:代码优化
class Solution {
public:
bool Find(int target, vector<vector<int> > array) {
int rowCount = array.size();
int colCount = array[0].size();
int i,j;
for(i=rowCount-1,j=0;i>=0&&j<colCount;)
{
if(target == array[i][j])
return true;
if(target < array[i][j])
{
i--;
continue;
}
if(target > array[i][j])
{
j++;
continue;
}
}
return false;
int a = array[0].size() - 1;
int b = array.size() - 1;
int i = 0;
if(a >= 0 && b >= 0)
{
while(array[b][i] != target)
{
if(array[b][i] > target)
--b;
else if(array[b][i] < target)
++i;
if(b < 0 || i > a)
return false;
}
}
else
return false;
return true;
}
};
题目:替换空格
请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
思路:先统计空格数量,再从后往前移动,这样只需要移动一次
提高:代码优化
class Solution {
public:
void replaceSpace(char *str,int length) {
int i = 0, space_back = 0, alphabet_length = 0;
while(str[i] != '\0')
{
++alphabet_length;
if(str[i] == ' ')
++space_back;
++i;
}
int new_length = alphabet_length + 2*space_back;
//从后往前替换
if(new_length > length)
return ;
while(alphabet_length >= 0)
{
// new_length--; //长了一位
if(str[alphabet_length] != ' ')
{
str[new_length--] = str[alphabet_length];
}
else
{
str[new_length--] = '0';
str[new_length--] = '2';
str[new_length--] = '%';
}
--alphabet_length;
}
str[new_length] = '\0';
}
};
题目:调整数组顺序使奇数位于偶数前面
思路:一、用类似冒泡的方法逐个交换相邻的数,二、用一个新数组,分别将奇数和偶数加入
提高:代码优化,解题思想
class Solution {
public:
void reOrderArray(vector<int> &array) {
int flag = 0;
for(int i = 0; i != array.size(); ++i)
{
for(int j = 1; j != array.size(); ++j)
{
if(array[j] % 2 == 1 && array[j - 1] % 2 == 0)
{
flag = array[j];
array[j] = array[j-1];
array[j - 1] = flag;
}
}
}
}
};
题目:字符串的排列
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
题目:数组中出现次数超过一半的数字
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
思路:若这个数组中有一个数字超过一半,则利用一个统计变量times,那么最后那个使times为正的数就是要求的数;若不存在超多一半的数字,则无意义。
提高:这是利用数组特点的解法,还可以利用算法来解
int MoreThanHalfNum_Solution(vector<int> numbers) {
int length = numbers.size();
int time = 1;
int result = numbers[0];
for(int i = 1; i < length; ++i)
{
if(time == 0)
{
result = numbers[i];
time = 1;
}
else if (result == numbers[i])
++time;
else
--time;
}
time = 0;
for(int i = 0; i < length; ++i)
{
if(numbers[i] == result)
++time;
}
return (time > length / 2) ? result : 0;
}
题目:最小的k个数
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
思路:利用冒泡算法,只需要排k次,其他的排序算法需要排所有。
提高:有很多种排序方法都需要会写,还可以堆排序。
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
int length = input.size();
vector<int> ivec;
if(k > length)
{
return ivec;
}
int a = 0;
for(int i = 0; i < k; ++i)
{
for(int j = i; j < length; ++j)
{
if(input[j] < input[i])
{
a = input[j];
input[j] = input[i];
input[i] = a;
}
}
ivec.push_back(input[i]);
}
return ivec;
}
};
题目:连续子数组的最大和
HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)
思路:需要用一个变量做参照,排除掉最后的负数。
提高:代码优化,用动态规划来计算
class Solution {
public:
int FindGreatestSumOfSubArray(vector<int> array) {
int length = array.size();
if(array.size() == 0)
return 0;
int sum = array[0];
int SUM = array[0];
for(int i = 1; i < length; ++i)
{
if(sum >= 0)
{
sum += array[i];
if(array[i] > 0)
{
SUM = sum;
}
}
else
{
if(sum < array[i])
sum = array[i];
}
if(sum > SUM)
SUM = sum;
}
return SUM;
}
};
题目:把数组排成最小的数
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
思路:先将数组里的数据进行排序,然后再排接
提高:代码优化(自己写一个自定义的排序)
class Solution {
public:
static bool cmp(int a, int b)
{
string A = "";
string B = "";
A += to_string(a);
A += to_string(b);
B += to_string(b);
B += to_string(a);
return A < B;
}
string PrintMinNumber(vector<int> numbers) {
string str;
if(numbers.size() == 0)
return str;
sort(numbers.begin(), numbers.end(),cmp);
for(int i = 0; i < numbers.size(); ++i)
{
str += to_string(numbers[i]);
}
return str;
}
};
题目:第一个只出现一次的字符位置
在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写)
思路:利用map进行统计,然后找出次数为1的字符位置。
提高:利用map的时间复杂度是多少?利用hash是多少?
class Solution {
public:
int FirstNotRepeatingChar(string str) {
map<char, int> ismap;
if(str.size() == 0)
return -1;
for(int i = 0; i < str.size(); ++i)
{
++ismap[str[i]];
}
for(int i = 0; i < str.size(); ++i)
if(ismap[str[i]] == 1)
return i;
return -1;
}
};
题目:数组中的逆序对
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
题目:数字在排序数组中出现的次数
统计一个数字在排序数组中出现的次数。
思路:找出该数字在数组中的两头,相减。
提高:代码优化
class Solution {
public:
int GetNumberOfK(vector<int> data ,int k) {
int times = 0;
int length = data.size();
int front = 0;
int back = length - 1;
int mid = 0;
while(front <= back)
{
mid = (front + back) / 2;
if(data[mid] < k)
{
front = mid + 1;
}
else
{
back = mid - 1;
}
}
times = front;
front = 0;
back = length - 1;
while(front <= back)
{
mid = (front + back) / 2;
if(data[mid] <= k)
{
front = mid + 1;
}
else
{
back = mid - 1;
}
}
return (back - times) + 1;
}
};
题目:左旋转字符串
汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!
思路:1、直接根据题目意思求解。2、用3次翻转的方法求解
提高:代码优化
class Solution {
public:
string LeftRotateString(string str, int n) {
string sr;
if(str.size() == 0)
{
return sr;
}
for(int i = n; i < str.size(); ++i)
{
sr += str[i];
}
for(int i = 0; i < n; ++i)
{
sr += str[i];
}
return sr;
/*
int len = str.length();
if(0 == len || 0 == n)
{
return str;
}
string &temp = str;
fun_Reversal(temp, 0, n - 1);
fun_Reversal(temp, n, len - 1);
fun_Reversal(temp, 0, len - 1);
return str;
}
void fun_Reversal(string &str, int begin, int end)
{
char temp;
while(begin < end)
{
temp = str[begin];
str[begin] = str[end];
str[end] = temp;
begin++;
end--;
} */
}
};
题目:翻转单词顺序列
牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?
思路:先把单词整体翻转,然后根据空格再逐个翻转
提高:代码优化
void fun_Reversal(string& str, int front, int back)
{
char a;
while(front < back)
{
a = str[front];
str[front] = str[back];
str[back] = a;
++front;
--back;
}
}
string ReverseSentence(string str) {
int length = str.size();
int front = 0;
int back = length - 1;
if(length <= 1)
return str;
fun_Reversal(str, 0, back); //从头到尾翻转
for(int i = 0; i < length; ++i)
{
if(str[i] == ' ')
{
fun_Reversal(str, front, i - 1);
front = i + 1;
}
if(i == back)
{
fun_Reversal(str, front, back);
}
}
return str;
/*
int len = str.length() - 1;
if(len <= 1)
{
return str;
}
fun_Reversal(str, 0, len);
int begin = 0;
int end = 0;
while(end <= len)
{
while(str[end] != ' ' && (end <= len))
{
end++;
}
fun_Reversal(str, begin, end - 1);
begin = end + 1;
end++;
}
return str;
}
void fun_Reversal(string &str, int begin, int end)
{
char temp;
while(begin < end)
{
temp = str[begin];
str[begin] = str[end];
str[end] = temp;
begin++;
end--;
} */
}
};