319 灯泡开关
初始时有 n 个灯泡处于关闭状态。第一轮,你将会打开所有灯泡。接下来的第二轮,你将会每两个灯泡关闭第二个。
第三轮,你每三个灯泡就切换第三个灯泡的开关(即,打开变关闭,关闭变打开)。第 i 轮,你每 i 个灯泡就切换第 i 个灯泡的开关。直到第 n 轮,你只需要切换最后一个灯泡的开关。
找出并返回 n 轮后有多少个亮着的灯泡。
思路:思路判断因子数目,奇数:偶数个因子灭,奇数个因子开;偶数:偶数个因子灭,奇数个因子开。所以总的来说,有偶数个因子就灭,奇数个因子就亮。最后一轮有多少个灯泡亮,如果按照这样的思路就是 O ( n 2 ) O(n^2) O(n2)的时间复杂度。
class Solution {
public:
int bulbSwitch(int n) {
if(n == 0){
return 0;
}
int ans = 0;
for(int i = 1;i <= n ; i++){//待判断整数
int count = 1;//默认1为因子
for(int j = 2 ; j <= i ; j++){ //因子个数判断,从2开始判断
if(i % j == 0){ count++; }
}
if(count % 2 == 1){//奇数个因子的整数位的灯泡会亮
ans++;
}
}
return ans;
}
};
果然,超出了时间限制,降低时间复杂度:实际上,只有完全平方数的因子数是奇数,其他数的因子数都是偶数。因此,我们只需要找到1到n之间的完全平方数的个数即可。其实就是对n开平方,就可以直到他之前有多少个完全平方数了。
class Solution {
public:
int bulbSwitch(int n) {
return (int)sqrt(n);
}
};
官方题解:sqrt(n) × sqrt(n+0.5) √
405 数字转16进制
给定一个整数,编写一个算法将这个数转换为十六进制数。对于负整数,我们通常使用 补码运算 方法。
注意:
十六进制中所有字母(a-f)都必须是小写。
十六进制字符串中不能包含多余的前导零。如果要转化的数为0,那么以单个字符’0’来表示;对于其他情况,十六进制字符串中的第一个字符将不会是0字符。
给定的数确保在32位有符号整数范围内。
不能使用任何由库提供的将数字直接转换或格式化为十六进制的方法。
思路:先进行负数补码转换,然后位运算转换成16进制的字符串
class Solution {
public:
string toHex(uint32_t num) {
uint32_t mask = 0x8000;
string ans;
if(num >> 15 == 1){//先除符号位按位取反,再+1
num ^= mask;
num += 1;
}
while(num){
uint32_t x = 0;
for(int i = 1 ; i < 5 ; i++){
x += (num >> (16-i)) * pow(2,4-i);
}
if(x > 9){ans.push_back( (x-10) + 'a');}
else{ans.push_back( x + '0' );}
num <<= 4;
}
return ans;
}
};
这个题可以看下之前用过mask的代码【6.24 476数字的补数】
class Solution{
public:
string toHex(int num){
//负数补码处理,使用转型static_cast<uint32_t>(num)即可
uint32_t n = static_cast<uint32_t>(num);
string ans;
//每次循环取四位,取低四位使用与运算,不要使用位运算了!!!
//判断大小时,uint32_t与int之间可以直接比较
while(n && ans.size() < 8){
uint32_t x = n & 0xf;
if(x > 9){
ans.push_back( (x-10) + 'a');
}else{
ans.push_back( x + '0');
}
n >>= 4;
}
//不要忘记翻转输出!!
reverse(ans.begin() , ans.end());
return ans;
}
};
大思路是没有问题的,在处理负数以及提取四位转换为十六进制字符串的时候需要【积累】!!其实差不多就是把这道题重新做一遍了,review的时候重新做一遍就好了。
171 Excel列表序号
给你一个字符串 columnTitle ,表示 Excel 表格中的列名称。返回 该列名称对应的列序号 。
例如:
A -> 1
B -> 2
C -> 3
…
Z -> 26
AA -> 27
AB -> 28
…
class Solution {
public:
int titleToNumber(string columnTitle) {
//一个个提取出来就好,26进制
int len = columnTitle.size();
int ans = 0;
for(int i = 0 ; i < len ; i++){
int m = columnTitle[i] - 'A' + 1;
ans += m * pow( 26 , len-i-1 );
}
return ans;
}
};
168 Excel表列名称
给你一个整数 columnNumber ,返回它在 Excel 表中相对应的列名称。
例如:
A -> 1
B -> 2
C -> 3
…
Z -> 26
AA -> 27
AB -> 28
…
class Solution {
public:
string convertToTitle(int columnNumber) {
string ans;
int num = columnNumber - 1;
while(num){
if(num%26 != 0){
ans.push_back( num%26 -1 + 'A');
}else{
ans.push_back('Z');
}
num /= 26;
}
reverse(ans.begin(), ans.end());
return ans;
}
};
原代码在计算每一位时需要调整 columnNumber,columnNumber-- 确保处理0-25范围内的字符而不是1-26。
class Solution {
public:
string convertToTitle(int columnNumber) {
string ans;
int num = columnNumber;
while(num){
num--;
ans.push_back( num%26 + 'A');
num /= 26;
}
reverse(ans.begin(), ans.end());
return ans;
}
};