查找
题目:采用二分法在给定有序数组中查找特定的元素。
/**
* @参数说明:arr给定有序数组,arr[0]数组长度;key查找元素
* @返回值:查找元素数组所在索引,-1表示数组没有查找元素
*/
int binarySearch(int arr[], int key) {
int low = 1;
int high = arr[0];
do {
int mid = (low + high) >> 0x01;
if (key == arr[mid]) return mid;
if (key > arr[mid]) {
low = mid + 1;
}
else {
high = mid - 1;
}
} while (low <= high);
return -1;
}
二分法查找,也称为折半法,是一种在有序数组中查找特定元素的搜索算法。
二分法查找的思路如下:
确定查找区域[low,high](low初始值为1,high初始值为数组大小arr[0])的中间元素(mid=(low+high)/2),如果中间元素正好是目标元素,则查找结束,否则由中间元素与查找目标大小关系,确定新的查找区域:
(1)查找元素大于中间元素,low = mid + 1;
(2)查找元素小于中间元素,high = mid - 1;
(3)low > high,查找结束,查找区域内,没有查找元素。
二分法查找的时间复杂度O(log2n)。
题目:在一个字符串中找到第一个只出现一次的字符。如输入abaccdeff,则输出b。
/**
* @参数说明:目标字符串
* @返回值:首次只出现1次字符,字符串所在位置,-1表示没有满足条件
*/
int firstNotRepeatingChar(const string str)
{
int result = -1;
int* hashtable = new int[256];
for (size_t i = 0; i < 256; i++) {
hashtable[i] = 0;
}
for (size_t i = 0; i < str.length(); i++)
{
hashtable[str[i]]++;
}
for (size_t i = 0; i < str.length(); i++)
{
if ( hashtable[str[i]]==1 )
{
result = i;
break;
}
}
delete[] hashtable;
return result;
}
看到题目的第一反应是字符串从头开始取一个字符与其他字符相比较,如果没有重复的字符,则该字符就是只出现一次的字符,显然这种思路的时间复杂度是O(n2 )。这里我们使用哈希表的方式,存放每个字符的出现次数,然后遍历哈希表,以空间换时间,复杂度变成O(n)。
其他
题目:计算一个数的二进制表示有多少个1。
int countBits(int n) {
int count = 0;
while(n) {
n &= (n-1);
count++;
}
return count;
}
计算机中的减法,是通过补码相加实现的(a-b=a+(0-b),其中0,由最大数+1利用溢出得到),-1的补码为:1111…1111,记n(n≠0)的二进制表示为{ 0,1 }* 1 { 0 }* ,显然对于n-1,共有3种情况运算
1.低位:0 + 1 = 1
2.最低位1:1 + 1 = 0,产生进位
3.高位:X + 0 = X,产生进位,其中X={ 0,1 }*
由此可得:当n≠0时,可以通过n=n&(n-1)把n最低位1置0。