The gray code is a binary numeral system where two successive values differ in only one bit.
Given a non-negative integer n representing the total number of bits in the code, print the sequence of gray code. A gray code sequence must begin with 0.
For example, given n = 2, return [0,1,3,2]
. Its gray code sequence is:
00 - 0 01 - 1 11 - 3 10 - 2
Note:
For a given n, a gray code sequence is not uniquely defined.
For example, [0,2,3,1]
is also a valid gray code sequence according to the above definition.
For now, the judge is able to judge based on one instance of gray code sequence. Sorry about that.
解析:比较简单的是,n位,数值到2^n - 1; 根据数学公式,整数n的格雷码是 n 异或 (n/2),把所有的数输出即可:
class Solution {
public:
vector<int> grayCode(int n) {
vector<int> result;
const size_t size = 1 << n;
result.reserve(size); // reserve是容器预留空间,但在空间内不真正创建元素对象,所以在没有添加新的对象之前,不能引用容器内的元素。加入新的元素时,要调用push_back()/insert()函数。
for (int i = 0; i < size ; ++i)
result.push_back(binary_to_gray(i));
return result;
}
static unsigned int binary_to_gray(unsigned int n){
return n ^ (n >> 1);
}
};
如,测试n = 3;
另附 gray_to_binary(unsigned int g){
for (unsigned int mask = g >> 1; maks != 0; mask = mask >> 1)
g = g^ mask;
return g;
}
另一个方法:
又下面规律,找出:
这种方法才是应该掌握的,而不是记公式,应该会找规律
class Solution {
public:
vector<int> grayCode(int n) {
vector<int> result;
result.push_back(0);
for (int i = 0; i < n ; ++i)
{
int high_bit = 1 << i;
for (int j = result.size() - 1; j >= 0; --j)
result.push_back(high_bit | result[j]);
}
return result;
}
};
2.
Set Matrix Zeroes
Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place.
Did you use extra space?
A straight forward solution using O(mn) space is probably a bad idea.
A simple improvement uses O(m + n) space, but still not the best solution.
Could you devise a constant space solution?
解析: O(m + n)的方法,用一个行和列,记录某行某列有零,比全部记录[m][n]节省空间,
class Solution {
public:
void setZeroes(vector<vector<int> > &matrix) {
int m = matrix.size();
int n = matrix[0].size();
vector<bool> row(m,false);
vector<bool> col(n,false);
for (int i = 0; i < m ; ++i)
for (int j = 0; j < n ; ++j)
if (matrix[i][j] == 0)
{
row[i] = col[j] = true;
}
for (int i = 0; i < m ; ++i)
if (row[i])
fill(&matrix[i][0],&matrix[i][0] + n, 0);
for (int j = 0; j < n; ++j)
if (col[j])
for(int i = 0; i < m ; ++i)
matrix[i][j] = 0;
}
};
思路2,可以用第一行一列提前检查其是否有零,然再用这一行一列做对应的标记
class Solution {
public:
void setZeroes(vector<vector<int> > &matrix) {
int m = matrix.size();
int n = matrix[0].size();
bool firstrow_has_zero = false;
bool firstcol_has_zero = false;
for (int i = 0; i < m ; ++i)
if (matrix[i][0] == 0){
firstcol_has_zero = true;
break;
}
for (int j = 0; j < n; ++j)
if (matrix[0][j] == 0){
firstrow_has_zero = true;
break;
}
for (int i = 1; i < m; ++i)
for (int j = 1; j < n; ++j)
if (matrix[i][j] == 0){
matrix[i][0] = 0;
matrix[0][j] = 0;
}
//start
for (int i = 1; i < m; ++i)
if (matrix[i][0] == 0)
for (int j = 0; j < n; ++j)
matrix[i][j] = 0;
for (int i = 1; i < n; ++i)
if (matrix[0][i] == 0)
for (int j = 0; j < m; ++j)
matrix[j][i] = 0;
//end
/*可以用下面这个代替,不过这俩都注意,i,j都是从1开始,否则影响了eg:[0][0]等,影响以后的结果
for (size_t i = 1; i < m; i++)
for (size_t j = 1; j < n; j++)
if (matrix[i][0] == 0 || matrix[0][j] == 0)
matrix[i][j] = 0;
*/
if (firstrow_has_zero)
for (int i = 0; i < n; ++i)
matrix[0][i] = 0;
if (firstcol_has_zero)
for (int j = 0; j < m; ++j)
matrix[j][0] = 0;
}
};
3.
Gas Station
There are N gas stations along a circular route, where the amount of gas at station i is gas[i]
.
You have a car with an unlimited gas tank and it costs cost[i]
of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations.
Return the starting gas station's index if you can travel around the circuit once, otherwise return -1.
Note:
The solution is guaranteed to be unique.
解析: 这次很容易想到两个for循环,不过时间可能超时,仔细分析下,可以发现,如果能跑一圈,那整个圆的gas -cost (定义为total)应该大于0,接下来如何确定起点的问题,用一个sum在循环里找, 如果第一次sum < 0 时,则依次为下一个起点,而其前面的肯定都大于0,所以可以形成圈(在total大于等于0的情况下)。
class Solution {
public:
int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {
int sum = 0, total = 0, j = -1;
for (int i = 0; i < gas.size(); ++i){
sum += gas[i] - cost[i]; //用来找起点
total += gas[i] - cost[i]; //用来判断是否可以走一圈,分开看问题了
if (sum < 0){
j = i;
sum = 0;
}
}
if (total >= 0) return j + 1; //可以浓缩为return total>=0 ? j + 1: -1;
else return -1;
}
};
4.
Candy
There are N children standing in a line. Each child is assigned a rating value.
You are giving candies to these children subjected to the following requirements:
- Each child must have at least one candy.
- Children with a higher rating get more candies than their neighbors.
What is the minimum candies you must give?
解析: 这题先从最少需要n,然后从左和右各找比前一个高的情况的累加,至少需要n是每个人有一个,如果有rating比其高的,最少加1,basic从0开始累加比其高的阶梯情况,若遇到比起低的,则把basic返回原始值,重新计算,而左边扫描后再从右边,注意其ca[i]已经有原始值了,可能在左边时满足情况,右边时足够大,所以要max出值,自己曾经想从一边都解决,首先思路不对,能分开分析的问题,要分开,都在左边太乱,或者不可行。
class Solution {
public:
int candy(vector<int> &ratings) {
int n = ratings.size();
int sum = n;
vector<int> ca(n);
for (int i = 1,basic = 0; i < n; ++i)
{
if (ratings[i] > ratings[i - 1])
ca[i] = ++basic;
else
basic = 0;
}
for (int i = n - 2, basic = 0; i >= 0; --i)
{
if (ratings[i] > ratings[i + 1])
ca[i] = max(++basic,ca[i]);
else basic = 0;
}
for (int i = 0; i < n; ++i)
sum += ca[i];
return sum;
}
};