Вопрос интервью 16.01.Поменяться номерами
Название Описание:
Напишите функцию, которая напрямую меняет местами нейтральное и нейтральное значения без использования numbers = [a, b]
временной a
переменной b
.
Идеи:
см. примечания
class Solution {
public:
vector<int> swapNumbers(vector<int>& numbers) {
numbers[0] = numbers[0] ^ numbers[1];
numbers[1] = numbers[0] ^ numbers[1]; // (numbers[0] ^ numbers[1]) ^ numbers[1] = numbers[0]
numbers[0] = numbers[0] ^ numbers[1]; // (numbers[0] ^ numbers[1]) ^ numbers[1] = numbers[0]
return numbers;
}
};
1342. Количество операций для преобразования числа в 0
Название Описание:
Учитывая неотрицательное целое число num
, верните количество шагов, необходимых для его преобразования в 0. Если текущее число четное, его нужно разделить на 2, иначе вычесть 1.
Идеи:
Этот вопрос задавался раньше с использованием нерекурсивного метода;
Можно использовать рекурсию, выход в том, что когда num равно 0, количество шагов операции равно 0;
Никакой рекурсии, просто обычный расчет;
class Solution {
public:
int numberOfSteps(int num) {
if (num == 0) {
return 0;
}
if (num & 1) {
return numberOfSteps(num-1) + 1;
}
return numberOfSteps(num/2) + 1;
// int cnt = 0;
// while(num) {
// if (num % 2) num = num - 1;
// else num = num / 2;
// cnt ++;
// }
// return cnt;
}
};
Название Описание:
После инвертирования двоичного представления целого числа (0 становится 1, 1 становится 0), а затем преобразует его в десятичное представление, можно получить дополнение этого целого числа.
Например, двоичное представление целого числа 5 — это «101», которое инвертируется, чтобы получить «010», и преобразуется обратно в десятичное представление, чтобы получить дополнение до 2.
Дано целое число, выведите его дополнение.
Идеи:
Сначала найдите наименьшее k, большее или равное num, если k равно num (в этот момент num равно 0 или 1, за которым следует несколько нулей), то результат (несколько нулей становятся 1), то есть k-1; в противном случае результат k- 1-число;
Далее, выраженный в двоичных битах:
Например: num = 1000000, тогда значение k>=num равно k=1000000. В это время, num==k, в результате все следующие шесть нулей становятся 1, то есть ans= 111111, k-1;
num = 1001001, тогда значение k>=num равно k=10000000. В это время, num<k, сначала замените все 7 нулей за k на 1, то есть k-1= 1111111, и результат в этот момент будет ans = (k-1)-num, то есть 110110;
class Solution {
public:
int findComplement(int num) {
unsigned int k = 1; //2^31
while (num > k) {
k <<= 1;
}
if (num == k) {
return k - 1;
}
return k - 1 - num;
}
};
Название Описание:
Учитывая целочисленный массив nums, найдите максимальное значение, которое можно получить с помощью побитового ИЛИ с подмножествами nums, и верните количество различных непустых подмножеств, которые можно получить с помощью побитового ИЛИ.
Массив a считается подмножеством массива b, если его можно получить удалением некоторых элементов из массива b (или нет). Если позиции нижних индексов выбранных элементов различны, два подмножества считаются разными.
Выполняет побитовое ИЛИ над массивом a, и результат равен a[0] ИЛИ a[1] ИЛИ ... ИЛИ a[a.length - 1] (индексы начинаются с 0).
Идеи:
Бит ИЛИ: если один из двух двоичных битов равен 1, результат равен 1;
Диапазон чисел не более 16, поэтому количество подмножеств не более 2 в 16-й степени;
каждое подмножество указывает, взято ли число или нет, поэтому ему может соответствовать двоичный бит, а двоичный бит равен 1, чтобы указать, что он взят, что 0 означает, что не брать,
перечислить все подмножества, вычислить бит или значение подмножества, а затем взять наибольшее.Когда есть одинаковые значения, счетчик накапливается, и, наконец возвращается значение счетчика.
class Solution {
public:
int countMaxOrSubsets(vector<int>& nums) {
int maxv = -1, maxc = 0;
int n = nums.size();
for (int i = 0; i < (1 << n) ; ++ i) {
int ans = 0;
for (int j = 0; j < n; ++ j) {
if (i & (1 << j)) {
ans |= nums[j];
}
}
if (ans > maxv) {
maxv = ans;
maxc = 1;
}else if (ans == maxv) {
maxc ++;
}
}
return maxc;
}
};