1.给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
int* twoSum(int* nums, int numsSize, int target) {
int min=INT_MAX;
int i=0;//循环变量
for(i=0;i<numsSize;i++)
{
if(nums[i]<min)
min=nums[i];
}
int max=target-min;
int length=max-min+1;//Hash length
int *Hashtable=(int *)malloc(length*sizeof(int));
int *ans=(int *)malloc(2*sizeof(int));
for(i=0;i<length;i++)
{
Hashtable[i]=-1;
}
for(i=0;i<numsSize;i++)
{
if(nums[i]-min<length)
{
if(Hashtable[target-nums[i]-min]!=-1)
{
ans[0]=Hashtable[target-nums[i]-min];
ans[1]=i;
return ans;
}
Hashtable[nums[i]-min]=i;
}
}
free(Hashtable);
return NULL;
}
2.给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
方法一(按位异或)
int singleNumber(int* nums, int numsSize) {
int ans=0;
for(int i=0;i<numsSize;i++)
ans^=nums[i];
return ans;
}
下面举例说明∧运算符的应用:
(1)使特定位翻转 假设有01111010,想使其低4位翻转,即1变为0,0变为1。可以将它与00001111进行∧运算,即 结果值的低4位正好是原数低4位的翻转。要使哪几位翻转就将与其∧运算的该几位置为1即可。这是因为原数中值为1的位与1进行∧运算得0,原数中的位值0与1进行∧运算的结果得1。
(2)与0相∧,保留原值 如012∧00=012 因为原数中的1与0进行∧运算得1,0∧0得0,故保留原数。
(3)交换两个值,不用临时变量 假如a=3,b=4。想将a和b的值互换,可以用以下赋值语句实现: a=a∧b;
b=b∧a;
a=a∧b;
可以用下面的竖式来说明:即等效于以下两步:
① 执行前两个赋值语句:“a=a∧b;”和“b=b∧a;”相当于b=b∧(a∧b)。而b∧a∧b等于a∧b∧b。b∧b的结果为0,因为同一个数与本身相∧,结果必为0。因此b的值等于a∧0,即a,其值为3。
② 再执行第三个赋值语句:a=a∧b。由于a的值等于(a∧b),b的值等于(b∧a∧b),因此,相当于a=a∧b∧b∧a∧b,即a的值等于a∧a∧b∧b∧b,等于b。 a得到b原来的值。 在【二进制值运算】中:不同为1,相同为0,如1001异或1010等于0011。
异或也叫半加运算,其运算法则相当于不带进位的二进制加法:二进制下用1表示真,0表示假,则异或的运算法则为:0异或0=0,1异或0=1,0异或1=1,1异或1=0(同为0,异为1),这些法则与加法是相同的,只是不带进位。
方法二(哈希表)
(待补充)
3.编写一个算法来判断一个数是不是“快乐数”。
一个“快乐数”定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是无限循环但始终变不到 1。如果可以变为 1,那么这个数就是快乐数。
示例:
输入: 19
输出: true
解释:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1