目录
0~n-1中缺失的数字
题目
题解
public int missingNumber(int[] nums) {
for(int i=0;i<nums.length;i++){
if(nums[i]!=i){
return i;
}
}
return nums.length;
}
二叉搜索树的第k大节点
题目
题解
思路:由于二叉搜索树中序遍历得到的序列升序的,因此中序遍历的逆序得到的序列就是降序的,通过右-中-左的方式遍历二叉搜索树,得到的第k个节点就是第k大的
代码:
private int count=0;
private int res=0;
public int kthLargest(TreeNode root, int k) {
inorder(root,k);
return res;
}
public void inorder(TreeNode root,int k){
if(root==null) return;
inorder(root.right,k);
count++;
if(count==k) res=root.val;
inorder(root.left,k);
}
二叉树的深度
题目
题解
代码:
public int maxDepth(TreeNode root) {
if(root==null) return 0;
int leftH=maxDepth(root.left);
int rightH=maxDepth(root.right);
return leftH>rightH?leftH+1:rightH+1;
}
平衡二叉树
题目
题解
代码:
public boolean isBalanced(TreeNode root) {
return getDepth(root)>=0;
}
public int getDepth(TreeNode root){
if(root==null) return 0;
int leftH=getDepth(root.left);
int rightH=getDepth(root.right);
if(leftH>=0 && rightH>=0 && Math.abs(leftH-rightH)<=1){
return leftH>rightH?leftH+1:rightH+1;
}else {
return -1;
}
}
数组中数字出现的次数(一)
题目
题解
public int[] singleNumbers(int[] nums) {
int[] ans=new int[2];
int ret=0;
for(int num:nums){
ret^=num;
}
int offset=0;
while((ret&1)==0){
ret>>=1;
offset++;
}
for(int num:nums){
if(((num>>offset) & 1) ==0){
ans[0]^=num;
}else {
ans[1]^=num;
}
}
return ans;
}
数组中数字出现的次数
题目
题解
思路:我们需要统计所有数字在某一位置的和能不能被3整除,如果不能被3整除,说明那个只出现一次的数字的二进制在那个位置是1……把32位全部统计完为止
代码:
public int singleNumber(int[] nums) {
int ret=0;
for(int i=0;i<32;i++){
int oneCount=0;
//统计第i位中1的个数
for(int j=0;j<nums.length;j++){
oneCount+=(nums[j]>>i) & 1;
}
if(oneCount%3==1){
ret |= 1<<i;
}
}
return ret;
}
和为s的两个数字
题目
题解
代码:
public int[] twoSum(int[] nums, int target) {
int left=0;
int right=nums.length-1;
while(left<right){
if(nums[left]+nums[right]==target){
return new int[]{nums[left],nums[right]};
}else if(nums[left]+nums[right]<target){
left++;
}else {
right--;
}
}
return new int[]{-1,-1};
}
和为s的连续正数序列
题目
题解
思路:滑动窗口+双指针,定义l,r分别指向窗口的左右边界,s保存窗口中所有数的和
初始值:l为1,r为2,s为3
比较s与target
- 当s==target时,将窗口中的序列加入到结果集
- 当s < target,r++,扩大窗口,同时更新元素和s
- 当s > target,l++,缩小窗口,同时更新元素和s
当l>=r时,跳出循环,因为题目要求序列最少包含两个元素
代码:
public int[][] findContinuousSequence(int target) {
List<int[]> ret=new ArrayList<>();
int l=1;
int r=2;
int s=3;
while(l<r){
if(s==target){ //将当前窗口中的序列加入到结果集
int[] tmp=new int[r-l+1];
for(int i=l;i<=r;i++){
tmp[i-l]=i;
}
ret.add(tmp);
}
if(s<target){ //如果窗口中所有数的序列和小于target,r向后移动一位,扩大窗口,同时s+=r
r++;
s+=r;
}else { //如果窗口中所有数组成的序列和大于等于target,l向后移动一位,缩小窗口,同时s-=r
s-=l;
l++;
}
}
return ret.toArray(new int[0][]);
}
翻转单词顺序
题目
题解
public String reverseWords(String str) {
String[] ss=str.trim().split(" ");
StringBuffer sb=new StringBuffer();
for(int i=ss.length-1;i>=0;i--){
if(ss[i].equals("")) continue;
sb.append(ss[i]+" ");
}
return sb.toString().trim();
}
左旋字符串
题目
题解
public String reverseLeftWords(String s, int n) {
return s.substring(n)+s.substring(0,n);
}
滑动窗口的最大值
题目
题解
代码:
private Deque<Integer> queue=new LinkedList<>();
public int[] maxSlidingWindow(int[] nums, int k) {
int n=nums.length;
int[] ret=new int[n-k+1];
for(int i=0;i<k;i++){
while(!queue.isEmpty() && nums[i]>=nums[queue.peekLast()]){
queue.pollLast();
}
queue.offerLast(i);
}
ret[0]=nums[queue.peekFirst()];
for(int i=k;i<n;i++){
while(!queue.isEmpty() && nums[i]>=nums[queue.peekLast()]){
queue.pollLast();
}
queue.offerLast(i);
while(queue.peekFirst()<=i-k){
queue.pollFirst();
}
ret[i-k+1]=nums[queue.peekFirst()];
}
return ret;
}