开始慢慢恢复刷题(基于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);
}
}