05.01
class Solution {
public int insertBits(int N, int M, int i, int j) {
int left=N>>j>>1;
left=left<<j<<1;
int mid=M<<i;
int last=N&((1<<i)-1);//取一个数低位的方法,1左移i位后减一,得到一个i位全为1的数,再与原数与
return left | mid | last;
}
}
0412
class Solution {
int ans=0;
public int pathSum(TreeNode root, int sum) {
if(root==null) return 0;
dfs(root,0,sum);
if(root.left != null) pathSum(root.left,sum);
if(root.right != null) pathSum(root.right,sum);
return ans;
}
public void dfs(TreeNode root,int S, int sum){
if(root==null) return;
if(S+root.val==sum) ans++;
dfs(root.left,S+root.val,sum);
dfs(root.right,S+root.val,sum);
}
}
/**树的深度优先遍历等于先序遍历 */
这里考察了dfs的用法,dfs类似先序遍历,它的原则是从根节点出发,只要存在路径就一直走下去,直到root等于null才返回上一层,寻找是否有其他路径可以走。
利用dfs求路径的条数,我们把每一个节点都看作一个根节点,对其进行dfs。
0503、2476
class Solution {
public int reverseBits(int num) {
String s=Integer.toBinaryString(num);
int result=0,pre=0,cur=0;
for(int i=0;i<s.length();i++){
if((int)s.charAt(i)-'0'==1){
pre++;
}else{
cur=pre;
pre=0;
}
result=Math.max(pre+cur+1,result);
}
return result==33?32:result;
}
}
这道题的逻辑很好理解,运动了动态规划的思想。用cur记录0之前的1个数,用pre记录遇到下一个0之前的1个数。
算了一个小时的原因在于类型转换不了解,转换过程是int——》String——》char——》int
在char型数字与int型比较时,要注意char型数字返回值是ASCII码,比如char 0ASCII码为48。
当前字符减去字符0 ,得到当前字符的int值。
0506/2478
class Solution {
public int convertInteger(int A, int B) {
//运用异或的思想,将a与b异或,得到不同位为1,再求1的个数
int result=A^B;
int i=0;
while(result!=0){
result=result&(result-1);
i++;
}
return i;
}
}
n-1的话,会一直向前寻找可借的位,从而跳过低位连续的0,而向最低位的1借位,借位后最低位的1变为0,原先最低位1的下一位从0变为1,其余位都不变,相与之后其它位不变,1(最低位1)0 &01(n-1对应的位)= 00,从而消除最低位的1。
0507\2479
class Solution {
public int exchangeBits(int num) {
return ((num & 0x55555555)<<1) | ((num & 0xaaaaaaaa)>>1);
}
}
int -> 32位
奇数位全1 -> 0101.... 表示为 0x55555555
偶数位全1 -> 1010.... 表示为 0xaaaaaaaa
0508
int 数据类型是4个字节,32位。而一个非黑即白(0/1)表示的像素点就是一位。
0804、2484
抛去动态规划的思想不谈,一开始的代码是这个样子。
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> lists=new ArrayList<>();
lists.add(new ArrayList<>());
for(int n : nums){
int size=lists.size();
for(int i=0;i<size;i++){
List<Integer> ls=new ArrayList();
ls=lists.get(i);
ls.add(n);
lists.add(ls);
}
}
return lists;
}
怎么读逻辑都是对的,但控制台输出为
又在idea中debug了一遍,运行步骤也没有错误。但可以观察到lists中元素始终只有一个,ls没有new成功,添加n也只是在lists中添加。
察觉到了可能的错误,list是不是不能用list赋值?
搜索发现:java中使用list1=list的赋值方式使得list1和list2指向同一个内存地址,两者会同时改变。
于是修改代码,用addAll();
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> lists=new ArrayList<>();
lists.add(new ArrayList<>());
for(int i = 0; i < nums.length; i++){
int size=lists.size();
for(int j=0;j<size;j++){
List<Integer> ls=new ArrayList<>();
ls.addAll(lists.get(i));
ls.add(nums[i]);
lists.add(ls);
}
}
return lists;
}
0806、2492
经典汉诺塔问题。
递归定义为:一个大的问题其实是由操作相同的小问题不断重复完成的。
递归的核心:
1.递归出口
2.重复做的事是什么
那么回答关于递归的两个问题
1.当盘子只有一个时,即最初的情况,直接将盘子从A移动到C。
2.它重复执行的步骤为:
1.将n-1个盘子从A移到B
2.将最大的盘子从A移到C
3.将n-1个盘子从B移到C(其实1与3做的重复相同)
0807、2506