Day9 LeetCode88 89 104(JAVA版)

目录

 

1. 合并两个有序数组(LeetCode 88 题)

1.1题目

1.2思路

1.3代码

2. 格雷编码(LeetCode 89 题)

2.1题目

2.2思路

2.3代码

3. 二叉树的最大深度(LeetCode 104题)

3.1题目

3.2思路

3.2代码


1. 合并两个有序数组(LeetCode 88 题)

1.1题目

 

1.2思路

方法一

最直接的方法就是把数组2放入数组一的尾部然后直接sort。

 

方法二

采用双指针的解法,因为这两个序列皆为有序的序列。均从头开始遍历,若小于等于及填充且递增其中一个指针,并填充至中间数组。若遍历完其中一个余下的另一个数组装入尾部即可。时间复杂度是(m+n)空间复杂度也是(m+n)。

 

方法三

这个方法我称之为最笨。(评论大佬提醒我可以用原有的空间直接进行操作,我想了想……写出来了这种东西。)

就是从nums1和nums2开始逐个比较,如果1大于2,那么1指针就向后移动一个。

本来以为不用sort的,直到我发现了这个问题。

如果输入

[4,5,6,0,0,0] 3 [1,2,3] 3

这样就会出现[1,4,5,6,2,3] 这样的结果,非常之笨。如果想正常进行遍历必须要sort新生成的nums2数组……

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int temp;
        int i = 0,j=0;
        int k = 0;
        while (i<m&&j<n){
            if(nums1[i]<=nums2[j]){
                i++;
            }else{
                temp = nums2[j];
                nums2[j] = nums1[i];
                nums1[i++]=temp;
                Arrays.sort(nums2);
            }
        }
        while (j<n) nums1[i++]=nums2[j++];
    }
}

方法四

也是双指针,不过这次改变了顺序,充分使用nums1的未使用位置,然后两个指针分别指m-1和n-1的位置。逐个进行比较,在最后补充未放入的nums2的余下数字。

1.3代码

class Solution {
  public void merge(int[] nums1, int m, int[] nums2, int n) {
    // two get pointers for nums1 and nums2
    int p1 = m - 1;
    int p2 = n - 1;
    // set pointer for nums1
    int p = m + n - 1;

    // while there are still elements to compare
    while ((p1 >= 0) && (p2 >= 0))
      // compare two elements from nums1 and nums2 
      // and add the largest one in nums1 
      nums1[p--] = (nums1[p1] < nums2[p2]) ? nums2[p2--] : nums1[p1--];

    // add missing elements from nums2
    System.arraycopy(nums2, 0, nums1, 0, p2 + 1);
  }
}

2. 格雷编码(LeetCode 89 题)

2.1题目

2.2思路

这里我采用镜像的方法进行填充,首先我们看到如果n=1时  是0,1。

如果n=2时  为00 01 10 11也就是0+1 0+0 2+1 2+0这样子

不妨从0到n遍历,初始值为0,每次刷新他的最高位的值,然后通过低位的数据累加即可得到首位为1后面位数的结果。

时间复杂度即为算出来值的数量,有多少值计算多少次。也就是2^n。空间复杂度同理,因为计算一次存储一次。

2.3代码

class Solution {
    public List<Integer> grayCode(int n) {
        List<Integer> res = new ArrayList<>(){{add(0);}};
        int head = 1;
        for(int i =0;i<n;i++){
            for(int j=res.size()-1;j>=0;j--){
                res.add(head+res.get(j));
            }
            head<<=1;//左移2位 一次相当于乘以2
        }
        return res;
    }
}

3. 二叉树的最大深度(LeetCode 104题)

3.1题目

3.2思路

树的遍历,采用递归的方法,如果后序遍历树,如果左子树,右子树为空,返回根为1。如果树为空,返回0。如果其中一个为空,返回另一个树的高度。

如果均不为空,采用后序遍历的方法,先去右子树,然后右子树然后返回最大值给根。也是DFS的方法,回溯整棵树。

树高度为n,时间复杂度为遍历所有节点的时间,为2^n-1。空间复杂度为1。

3.2代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int maxDepth(TreeNode root) {
        int deepth=0;
        if(root==null) return deepth;
        if(root.left==null&&root.right==null) return ++deepth;
        else{
            deepth++;
            if(root.left==null) deepth = deepth+maxDepth(root.right);
            else if(root.right==null) deepth = deepth+maxDepth(root.left);
            else deepth = deepth+Math.max(maxDepth(root.right),maxDepth(root.left));
        }
        return deepth;
    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值