(1)劍指17 打印從1到最大的n位數
法1:常規解法
class Solution {
public:
vector<int> printNumbers(int n) {
vector<int> res;
int max=pow(10,n);
for(int i=1; i<max; i++){
res.push_back(i);
}
return res;
}
};
法2:用iota
用法:
std::vector<int> foo;// 構造一個 vector 對象
foo.resize(15);
std::iota(foo.begin(), foo.end(), 9);// 將從 9 開始的 15 次遞增值賦值給 foo
//輸出結果:9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
class Solution {
public:
vector<int> printNumbers(int n) {
int max = pow(10, n) - 1;
vector<int> res(max);
//res.resize(max);//改變容器大小
iota(res.begin(), res.end(), 1);//從1開始,添加max個數字
return res;
}
};
法3:大數問題(沒懂)
(2)劍指43. 1~n整數中1出現的次數【中等,我覺得hard】
輸入一個整數 n ,求1~n這n個整數的十進制表示中1出現的次數。
例如,輸入12,1~12這些整數中包含1 的數字有1、10、11和12,1一共出現了5次。
示例 1:
輸入:n = 12
輸出:5
示例 2:
輸入:n = 13
輸出:6
思路:找規律
設N = abcde ,其中abcde分別爲十進制中各位上的數字。
如果要計算百位上1出現的次數,它要受到3方面的影響:
百位上的數字,百位以下(低位)的數字,百位以上(高位)的數字。
① 如果百位上數字爲0,百位上可能出現1的次數由更高位決定。
比如:12013,則可以知道百位出現1的情況可能是:
100~199,1100~1199,2100~2199,,...,11100~11199,一共1200個。
可以看出是由更高位數字(12)決定,並且等於更高位數字(12)乘以 當前位數(100)。
② 如果百位上數字爲1,百位上可能出現1的次數不僅受更高位影響還受低位影響。
比如:12113,則可以知道百位受高位影響出現的情況是:
100~199,1100~1199,2100~2199,,....,11100~11199,一共1200個。
和上面情況一樣,並且等於更高位數字(12)乘以 當前位數(100)。
但同時它還受低位影響,百位出現1的情況是:12100~12113,一共114個,
等於低位數字(113)+1。
③ 如果百位上數字大於1(2~9),則百位上出現1的情況僅由更高位決定,
比如12213,則百位出現1的情況是:
100~199,1100~1199,2100~2199,...,11100~11199,12100~12199,一共有1300個,
並且等於更高位數字+1(12+1)乘以當前位數(100)。
class Solution {
public:
int NumberOf1Between1AndN_Solution(int n)
{
int count = 0;//1的個數
int i = 1;//當前位
int current = 0,after = 0,before = 0;
while((n/i)!= 0){
current = (n/i)%10; //當前位數字
before = n/(i*10); //高位數字
after = n-(n/i)*i; //低位數字
//如果爲0,出現1的次數由高位決定,等於高位數字 * 當前位數
if (current == 0)
count += before*i;
//如果爲1,出現1的次數由高位和低位決定,高位*當前位+低位+1
else if(current == 1)
count += before * i + after + 1;
//如果大於1,出現1的次數由高位決定,//(高位數字+1)* 當前位數
else{
count += (before + 1) * i;
}
//前移一位
i = i*10;
}
return count;
}
};
(3)劍指62 圓圈中最後剩下的數字(約瑟夫環問題)(記)
不會,記住?
解釋 https://blog.csdn.net/u011500062/article/details/72855826
int lastRemaining(int n, int m){
int p=0;//只有1個人的情況下,勝利者下標爲0
for(int i=2;i<=n;i++)//從2個人開始依次用公示推出有i個人的情況下,勝利者下標p
p=(p+m)%i; //由下面可以推出,i個人時最終勝利者3的下標的規律
return p;
//下標:0 1 2 3 4
//數據:
// 0 1 2 3 4
// 3 4 0 1
// 1 3 4
// 1 3
// 3
}
(4)劍指64 求1+2+…+n
求 1+2+…+n ,要求不能使用乘除法、for、while、if、else、switch、case等關鍵字及條件判斷語句(A?B:C)。
示例 1:
輸入: n = 3
輸出: 6
示例 2:
輸入: n = 9
輸出: 45
思路:&&短路運算
區別:
1意思不同: &&是“與”的意思,||是“或者”的意思。
2 使用上不同:a && b:a和b同時爲true 才返回 true, 否則返回false;a || b:a或b任意一個爲true 就返回true , 否則返回false
3 兩者都表示運算,但是&&運算符第一個表達式不成立的話,後面的表達式不運算,直接返回。而&對所有表達式都得判斷。
class Solution {
public:
int Sum_Solution(int n) {
int ans = n;
ans && (ans += Sum_Solution(n - 1));
return ans;
}
};
(5)劍指65 不用加減乘除做加法(記)
俗話說的好:這題位運算還是背下來吧,畢竟位運算這種模擬加法用法基本就這題,很容易就忘掉。
13+11 = ?;
13 的二進制 1 1 0 1 -----a 13
11 的二進制 1 0 1 1 -----b 11
(a&b) <<1 -> 1 0 0 1 0 -----d 18
a^b -> 0 1 1 0 -----e 6
(d&e) <<1 -> 0 0 1 0 0 ------f 4
d^e -> 1 0 1 0 0 -----g 20
(f&g) <<1 -> 0 1 0 0 0 ------h 8
f^g -> 1 0 0 0 0 ------i 16
(h&i) <<1 -> 0 0 0 0 0 ------h 0 ---- --------退出循環
h^i -> 1 1 0 0 0 ------i 24
class Solution {
public:
int add(int a, int b) {
while(b!=0){
int tmp1=a^b;
// 注意LC c++不支持負值左移,需要強制轉換爲無符號數
int tmp2=(unsigned int)(a&b)<<1;
a=tmp1;
b=tmp2;
}
return a;
}
};