693. 交替位二进制数【简单题】【每日一题】
思路:【位运算】
- 排除特殊情况n=1,此时return true。
- 将n转为二进制字符串,依次将相邻两位数字进行异或运算。
- 异或运算的结果为flag,如果flag是0,说明相邻两位相同,返回false,如果flag是1,则判断下一组相邻两位数字,由于循环结束时未对最后一组数组判断,因此在函数的返回体那里需要返回flag是否等于1对最后一组进行判断。
代码:
class Solution {
public boolean hasAlternatingBits(int n) {
if ( n == 1){
return true;
}
String binary = Integer.toBinaryString(n);
char[] chars = binary.toCharArray();
int flag = chars[0] ^ chars[1],len = chars.length;
for (int i = 2; i < len; i++) {
if (flag == 0){
return false;
}else {
flag = chars[i-1] ^ chars[i];
}
}
return flag == 1;
}
}
227. 基本计算器 II【中等题】
思路:
- 字符串中的空格是没有意义的,先将其全部去掉。
- 定义LinkedList集合list_num用来存储数据。
- 定义flag来表示当前有效数据前方的运算符,默认为 + 。
- 遍历字符串,如果当前字符是数字,则从这个位置向后遍历,直到遇见非数字的字符为止,定义j为终止字符,那么有效数字即为字符串s从 i 到 j 截掉之后所表示的数字,用num来存储,并将 i 位置 更新到 j 位置。
- 如果当前字符不是数字(注意这里我指的的那个是步骤4中 i 位置没更新之前的 i位置字符),或者当前下标 i 已经等于 字符串长度了, 那么判断有效数字num前方的运算符flag是什么,+ 则 将 num 添加到数据集合的末尾; - 则将 num 取反后添加到数据集合的末尾;* 则将数据集合末尾的数据取出并删除,乘上现在的有效数字 num ,并将 积 添加到数据集合末尾; / 则将数据集合末尾的数据取出并删除,除以现在的有效数字 num,并将 商 添加到数据集合末尾,处理之后将 当前字符 cur 表示的运算符更新到flag中,i++遍历下一位字符。
- 最后将list_num中的每一个元素都取出来累加,将累加和返回即为答案,这里需要注意,要用取出元素并删除的操作来累加,不要用for循环遍历,两者之间运行时间相差十几毫秒,这是LinkedList的数据结构决定的。
代码:
class Solution {
public int calculate(String s) {
s = s.replaceAll(" ","");
LinkedList<Integer> list_num = new LinkedList<>();
int num = 0,len = s.length(),i = 0;
char flag = '+';
while (i<len){
char cur = s.charAt(i);
boolean isNum = Character.isDigit(cur);
if (isNum){
int j = i;
while (j < len){
if (Character.isDigit(s.charAt(j))){
j++;
}else {
break;
}
}
num = Integer.parseInt(s.substring(i,j));
i = j;
}
if (!isNum || i == len){
switch (flag){
case '+':
list_num.addLast(num);
break;
case '-':
list_num.addLast(-num);
break;
case '*':
list_num.addLast(list_num.removeLast()*num);
break;
case '/':
list_num.addLast(list_num.removeLast()/num);
break;
}
flag = cur;
i++;
}
}
int ans = 0;
while (!list_num.isEmpty()){
ans += list_num.removeLast();
}
return ans;
}
}
264. 丑数 II【中等题】
思路:【对官方题解的理解】
- 定义数组dp,其中dp[i]表示第i个丑数,第n个丑数即为dp[n],即返回dp[n]即可。
- 由于最小的丑数是1,所以dp[i] = 1。
- 当前dp[i]乘以2,3,5,这三个数为候选丑数,定义三个指针p2,p3,p5分别表示这三个候选丑数在dp数组中对应的下标,初始值均为1。
- i 从2开始遍历(n=1的话不走循环直接返回dp[i] = 1),到等于n结束。定义num2,num3,num5表示三个候选丑数的值,选中其中值最小的丑数加入dp数组。并判断这个被选中的丑数是num2,num3,num5这三个数中哪个幸运儿,如果哪个幸运儿被选中做丑数,就将它的下标往右移动一位,因为候补丑数的诞生只跟前一位丑数有关。
- 循环结束返回dp[n]即可。
代码:
class Solution {
public int nthUglyNumber(int n) {
int[] dp = new int[n+1];
dp[1] = 1;
int p2 = 1,p3 = 1,p5 = 1;
for (int i = 2; i <= n; i++) {
int num2 = dp[p2]*2,num3 = dp[p3]*3,num5 = dp[p5]*5;
dp[i] = Math.min(num2,Math.min(num3,num5));
if (dp[i] == num2){
p2++;
}
if (dp[i] == num3){
p3++;
}
if (dp[i] == num5){
p5++;
}
}
return dp[n];
}
}