開始慢慢恢復刷題(基於Java,二刷用C++/Python),主要是記錄一下思維,題目由簡單到困難,慢慢的完成
更新時間:2020.04.12(3 道簡單題目)
1. 左旋字符串
給定一串字符串,和旋轉的位置,然後調換兩段子字符串,通過substring(n)重組字符串即可,難度低,無技術性。
class Solution {
public String reverseLeftWords(String s, int n) {
return s.substring(n) + s.substring(0, n);
}
}
2. 猜數字
給定兩個整型數組,然後比較相同位置的數據是否相同,若相同就計數。思路就是count計數,然後循環數組比較,獲取相同的數量。缺點就是如果面對大數組的時候,雖然時間複雜度不變,但是循環+判斷還是會加大時間花銷和內存花銷。
class Solution {
public int game(int[] guess, int[] answer) {
int count = 0;
for (int i = 0; i < 3; i++)
if (guess[i] == answer[i]) count++;
return count;
}
}
3. 統計位數爲偶數的數字數量
給定一個數組,然後判斷數組內有多少個數位爲偶數的數字。
第一反應就是do...while + n/10,因爲結果是取整的,所以直到結果爲0的時候,偶數次就是偶數位。時間複雜度較高。
第二個想法就是換成字符串,整型轉字符串,然後統計長度,相當於簡化了第一反應的一個循環,string.length%2,爲0即偶數。
第三個想法就是搞個判斷,如果數據範圍不大,判斷條件也相對會較少。邊界值也好找。
class Solution {
public int findNumbers(int[] nums) {
int count = 0;
for(int i = 0; i < nums.length; i++){
if((nums[i]>=10 && nums[i]<= 99) || (nums[i]>=1000 && nums[i]<= 9999) || nums[i] == 100000 ){
count++;
}else continue;
}
return count;
}
}
---------------------4.20 更新----------------------------------
4. 數字變成0的次數
一個非負整數num ,請你返回將它變成 0 所需要的步數。 如果當前數字是偶數,你需要把它除以 2 ;否則,減去 1 。
很簡單的題目,但是可以做較多的優化,一般會選擇如下代碼:
class Solution {
public int numberOfSteps (int num) {
int count = 0;
while(num != 0){
count++;
if(num % 2 == 0)
num = num/2;
else
num--;
}
return count;
}
}
但是,學習過計算機組成原理、彙編之後,對於原碼、移碼、反碼、位運算、邏輯運算等操作應該不會陌生。使用二進制移碼相較於直接使用算術符號速度將會更快。雖然一般我們不會在乎這點微弱的時間差。但是作爲優化來說,還是非常值得去做的。
借鑑莊周の蝴蝶(作者名:zjw1221 )的解題思路及代碼,優化如下:
以32位二進制爲例, 例如15(0x0000000f):
遇奇減1, 即將末位1變爲0, 和0xfffffffe(-2)取&即可;
遇偶除2, 即右移一位即可;
兩種情況都需要次數加1.
1.迭代
class Solution {
public int numberOfSteps (int num) {
int count = 0;
while (num != 0) {
count++;
num = (num & 1) == 1 ? num & -2 : num >> 1;
}
return count;
}
}
2.遞歸
class Solution {
private int count = 0;
public int numberOfSteps (int num) {
if (num != 0) {
count++;
if ((num & 1) != 0)
numberOfSteps(num & -2);
else
numberOfSteps(num >> 1);
}
return count;
}
}
5. 給定整數的各數位的乘積與各數位的和之間的差
取餘是最好的選擇,然後想了點幺蛾子複雜化,硬是轉換類型浪費內存
class Solution {
public int subtractProductAndSum(int n) {
int sumRes = 0, modRes = 1, finRes = 0;
String len = String.valueOf(n);
for(int i = 0; i < len.length(); i++){
char a = len.charAt(i);
int b = a-'0';
sumRes = sumRes + b;
modRes = modRes * b;
}
finRes = modRes - sumRes;
return finRes;
}
}
取餘:
class Solution {
public int subtractProductAndSum(int n) {
int sumRes = 0, proRes = 1;
while (n!=0){
int num = n % 10;
sumRes += num;
proRes *= num;
n /= 10;
}
return proRes-sumRes;
}
}
6. 寶石與石頭
兩個字符串,一個代表寶石類型,一個表示包含寶石在內的所有的石頭,將石頭中的寶石個數統計出來,字符區分大小寫。
用了一個糟糕的時間複雜度O(m*n)的算法
class Solution {
public int numJewelsInStones(String J, String S) {
int count = 0;
for(int i=0; i<J.length(); i++){
char jew = J.charAt(i);
for(int j=0; j<S.length(); j++){
char stone = S.charAt(j);
if(jew == stone)
count++;
else
continue;
}
}
return count;
}
}
使用哈希表,將寶石存成散列表,然後判斷當前的石頭是不是在散列表中,時間複雜度O(n+m),解題代碼來自官方
class Solution {
public int numJewelsInStones(String J, String S) {
Set<Character> Jset = new HashSet();
for (char j: J.toCharArray())
Jset.add(j);
int ans = 0;
for (char s: S.toCharArray())
if (Jset.contains(s))
ans++;
return ans;
}
}
7. 生成每種字符都是偶數個的字符串
檢測數據有點差強人意(優化答案來自莊周の蝴蝶)
class Solution {
public String generateTheString(int n) {
return (n & 1) == 0 ? "p".repeat(n - 1)+"z" : "a".repeat(n);
}
}