面试编程题(四)
一、不用加减乘除做加法
写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。
数据范围:两个数都满足 −10≤n≤1000−10≤n≤1000
int Add(int num1, int num2 ) {while (num2 != 0) { //进位不为0则持续与相加结果进行相加int tmp = num1 ^ num2;//得到每位相加不考虑进位的数据num2 = (num1 & num2) << 1;//同1的位相加则会进位num1 = tmp;}return num1;
}
解法:二进制相加思想:与十进制相同,先计算不考虑进位的相加结果( 0+0 得0 , 1+1 进位得0 , 1+0 得1 ),使用异或可以取得; 然后计算相加的进位结果(同1 的位置左移一位即可),使用与后左移取得。
异或运算可以得到二进制位相加的结果(没有进位),而与运算后进行左移一位,可以得到进位(因为全1为1,1+1=10 ,(1&1)<<1 =10)。
牛客https://www.nowcoder.com/practice/59ac416b4b944300b617d4f7f111b215?tpId=13&tqId=23249&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
二、找到所有数组中消失的数组
给你一个含 n
个整数的数组 nums
,其中 nums[i]
在区间 [1, n]
内。请你找出所有在 [1, n]
范围内但没有出现在 nums
中的数字,并以数组的形式返回结果。
int* findDisappearedNumbers(int* nums, int numsSize, int* returnSize) {int* arr = (int*)calloc(numsSize + 1,sizeof(int)); // 多开辟一个空间,因为这个数组的下标对应1-n的数字for (int i = 0; i < numsSize; ++i) {if (arr[nums[i]] == 0) {arr[nums[i]] = 1;}}int count = 0;int* ret = (int*)malloc(sizeof(int) * numsSize);for (int i = 1; i < numsSize + 1; ++i) {if (arr[i] == 0) {ret[count++] = i;}}*returnSize = count;return ret;
}
这个方法比较简单粗暴,浪费空间较多。空间复杂度位O(n)。
还有更好的方法,将nums中的元素的绝对值作为下标去找nums对应的这个下标的元素,让他变为负数,最后遍历数组。如果一元素为正数,那么他的下标就没有在第一次遍历的时候通过数组元素对应的下标访问过。
int* findDisappearedNumbers(int* nums, int numsSize, int* returnSize) {for (int i = 0; i < numsSize; ++i) {if (nums[abs(nums[i]) - 1] > 0) {nums[abs(nums[i]) - 1] = -(nums[abs(nums[i]) - 1]);}}int count = 0;int* ret = (int*)malloc(sizeof(int) * (numsSize));for (int i = 0; i < numsSize; ++i) {if (nums[i] > 0) {ret[count++] = i + 1;}}*returnSize = count;return ret;
}
leetcodehttps://leetcode.cn/problems/find-all-numbers-disappeared-in-an-array/