Calculate the sum of two integers a and b, but you are not allowed to use the operator + and -.
Example:
Given a = 1 and b = 2, return 3.
個人思路:繞開+、-,利用循環和 += 與 -= 。
class Solution {
public:
int getSum(int a, int b) {
double x = a, y = b;
double c = fabs(y);
for (double i = 1; i <= c; i++) {
if (b > 0) a++;
if (b < 0) a--;
}
return a;
}
};
錯誤原因:特殊值的計算。a = 2147483647, b = -2147483647。Time Limit Exceeded
自己在電腦上跑結果是對的,然而循環次數太多了,浪費時間,比較笨的一種方法,年輕人,還是太傻太天真,還需要學習一個。
其他思路:
1.利用下標偏移自帶加法 by dimle
int getSum(int a, int b) {
auto c = (char*)(a);
return (int)((int64_t)(&c[b]));
}
把a變成一個地址為a的指針c,把它看成數組,偏移b後,地址變成a + b,再把地址轉成int。(補充學習:<inttypes.h>)
2.利用位運算 by vdvvdd
class Solution {
public:
int getSum(int a, int b) {
int sum = a;
while (b != 0)
{
sum = a ^ b;//calculate sum of a and b without thinking the carry
b = (a & b) << 1;//calculate the carry
a = sum;//add sum(without carry) and carry
}
return sum;
}
};
解釋:
class Solution {
public:
int getSum(int a, int b) {
// Take 1 + 2 for example in 4 bits.
// Same as 0001 + 0010
// Binary addition requires going through each bit position and
// generating a carry in bit, carry out bit and sum bit.
// For example, in bit position 0 in 0001 + 0010,
// carry in: 0, sum bit: carry in + 1 + 0 = 1, carry out: 0
// For bit position 1,
// carry in: 0, sum bit: carry in + 0 + 1 = 1, carry out: 0
// Using a truth table, we can figure out that
// sum bit = carry in xor bit_a xor bit_b.
// carry out = (carry in AND bit_a) OR (carry in AND bit_b) OR (bit_a AND bit_b)
// carry out becomes the carry in for the next bit position.
int result = 0x0;
int sum_bit = 0x0;
int carry_bit = 0x0;
int bitmask = 0x1;
int bit_a = 0x0;
int bit_b = 0x0;
int i = 0; // Keep track of what bit position im in.
while (bitmask != 0x0) {
// Isolate bits in each bit position.
bit_a = (a & bitmask) >> i;
bit_b = (b & bitmask) >> i;
// Calculate sum, carry_bit is a carry in now.
sum_bit = ((carry_bit ^ bit_a) ^ bit_b);
// Shift sum_bit to correct bit position, OR into result.
result |= (sum_bit << i);
// Calculate carry out, carry_bit is now a carry out after calculation.
carry_bit = ((bit_a & bit_b) | (carry_bit & bit_a)) | (carry_bit & bit_b);
// Shift bitmask over 1 to the left.
bitmask <<= 1;
// Increment bit position.
++i;
}
return result;
}
};
3. 另一種位運算 by cjchan0210
class Solution {
public:
int getSum(int a, int b) {
if(a && b) return getSum(a^b, (a&b) << 1);
else return a|b;
}
};
viewed as binary, c = (a&b)<<1 means carry bits, and d = a^b means sum without carry obviously...
and then get the sum of c and d...
if a or b is 0, return a or b, so that is a|b
拓展閱讀:https://discuss.leetcode.com/topic/50315/a-summary-how-to-use-bit-manipulation-to-solve-problems-easily-and-efficiently