赞
踩
跟着博主一起刷题
这里使用的是题库:
https://leetcode.cn/problem-list/xb9nqhhg/?page=1
剑指 Offer 55 - II. 平衡二叉树
这道题和上一篇文章中二叉树的深度如出一辙,这里求出左右子树的最大深度后判断即可。
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ class Solution { public boolean isBalanced(TreeNode root) { return maxDepth(root)!=-1; } private int maxDepth(TreeNode root) { if(root==null)return 0; int left=maxDepth(root.left); if(left==-1)return -1; int right=maxDepth(root.right); if(right==-1)return -1; if(Math.abs(left-right)>1){ return -1; } return Math.max(left,right)+1; } }
剑指 Offer 56 - I. 数组中数字出现的次数
我们知道,如果只有一个数字唯一出现,其余数字均出现两次,我们可以直接异或求解,但这里有两个还能用这种方法吗?
我的回答是:可以,我们全部异或后,设唯一出现的两个数字为a,b,那最终的结果就是:
a^b
既然a和b不相同,那么他们的二进制至少有一位是不相同的,那么我们就根据某一位的不相同来把我们的数字分为两组,两组再分别异或,得到结果。
难点:这个某一位是哪一位?
解答:根据异或的性质,相同为0,相异为1,可根据结果那位为1,得到该位不相同。
class Solution { public int[] singleNumbers(int[] nums) { int ab=0; for(int i:nums){ ab^=i; } int bit=0; while(bit<32){ if((ab&(1<<bit))!=0){ break; } bit++; } int a=0; int b=0; for(int i:nums){ if((i&(1<<bit))!=0){ a^=i; }else{ b^=i; } } int[] ret=new int[2]; ret[0]=a; ret[1]=b; return ret; } }
剑指 Offer 56 - II. 数组中数字出现的次数 II
和上题不同的时,这道题不能再异或了,得另寻他法。
我一开始的想法是,利用哈希表记录出现次数即可
class Solution {
public int singleNumber(int[] nums) {
Map<Integer,Integer> map=new HashMap<>();
for(int i:nums){
map.put(i,map.getOrDefault(i,0)+1);
}
for(int i:nums){
if(map.get(i)==1)return i;
}
return -1;
}
}
但是又想像上一题一样空间复杂度维持在O(1),必须使用其他方法。
上一题我们利用了a和b某位二进制位不同来分组异或,核心就是二进制位。那么这道题也是如此,注意看,一个数字出现三次,那么对于某一个二进制位来说,要么出现1三次,要么为0。那么我们将所有数字在不同二进制位1的个数算出来再取模3,得到的结果就是唯一出现的那个数字在该比特位的值。
比如
【1,1,1,3】
1二进制表示的最后四位:0001
3二进制表示的最后四位:0011
那么最后一位出现了4个1,%3得到1,即是唯一出现数字在最后一位的值,剩下的位以此类推即可。
public int singleNumber(int[] nums) {
int xor=0;
int[] bits=new int[32];
for(int i=0;i<nums.length;i++){
for(int j=0;j<32;j++){
bits[j]+=(nums[i]&(1<<j))==0?0:1;
}
}
int ret=0;
for(int i=0;i<32;i++){
ret<<=1;
ret|=bits[31-i]%3;
}
return ret;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。