欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

LeetCode简单难度题解(二)

程序员文章站 2024-03-18 12:56:46
...

35、搜索插入位置

循环数组 从后往前找,当匹配到第一个比目标值小的那个元素下标的时候 返回下标+1就是目标值要插入的位置,如果有正好匹配的值 直接返回下标

public int searchInsert(int[] nums, int target) {
    for(int i = nums.length - 1; i >= 0; i--){
        if(nums[i] == target){
            return i;
        }
        if(nums[i] < target){
            return i + 1;
        }
        if(i == 0){
            return 0;
        }
    }
    return -1; 
}

53、最大子序和

直接看代码注释吧,很简单的一道题

public static int maxSubArray3(int[] nums) {
    /*
        1 3 -5 2
        res = 1  sum = 1
        res = 4  sum = 4
        res = 4  sum = -1
        res = 4  sum = 2
     */
    int res = nums[0];
    int sum = nums[0];
    for (int i = 1; i < nums.length; i++){
         // 当前和加上当前值  都没有当前值大的话就  直接取当前值去很最大和比较
        sum = Math.max(nums[i], sum + nums[i]);
        res = Math.max(res, sum); // 最大和
    }
    return res;
}

方法二:

public static int maxSubArray(int[] nums) {
    // 数组中第一个元素   也是用来存储最大值的
    int res = nums[0];
    int sum = 0;
    for (int num : nums) {// 遍历所有数组
        if (sum > 0) sum += num;
        else sum = num;// 如果当和等于负数的时候  直接不要之前的和了  把当前值给sum
        res = Math.max(res, sum);// 更新最大的和  把res和  当前最大整数和相比   如果全都是负数的话就都直接进入这里比较
    }
    return res;
}

58、最后一个单词的长度

到目前为止最简单的题了
方法一 :
按空格拆分 取最后一段的长度!!

public int lengthOfLastWord(String s) {
    String [] strs = s.split(" +");
    if(s.trim().equals("")){
        return 0;
    }else{
        return strs[strs.length-1].length();
    }
}

方法二:
去掉前后空格 后 整体长度减去最后一个空格之前的长度 lastIndexOf是从0开始 最后多减一个1

public int lengthOfLastWord2(String s) {
    return s.trim().length() - s.trim().lastIndexOf(" ") - 1;
}

66、加一

这题分为三种情况
最后一位小于9的时候 直接加1 返回
最后一位d等于9的时候 当前位数归0表示进1接着走循环 当出现第一个小于9的时候加1返回
最后一种情况 例如 9999 加1 总位数会加1 当循环走完 还没有返回, 新建一个数组 第一位为0

public int[] plusOne(int[] digits) {
    if (digits == null || digits.length == 0) return digits;
    for (int i = digits.length - 1; i >= 0; i--){
        if (digits[i] < 9) { 
            digits[i]++;
            return digits;
        }else{ 
            digits[i] = 0;
        }
    }
    int[] res = new int[digits.length + 1];
    res[0] = 1;
    return res;
}

67、二进制求和

不断的取模 除2 最后考虑进位问题就行了
首先使用一个StringBuilder就可以防止不断的开辟新的空间
两数从后往前相加,定义一个用于记录进位的变量
最后循环走完的时候判断是否还有进位 有就把进位添加到StringBuilder中
反向输出 返回

public static String addBinary(String a, String b) {
    StringBuilder sb = new StringBuilder();
    int i = a.length() - 1;
    int j = b.length() - 1;
    int remainder = 0;
    while (i >= 0 || j >= 0) {
        int sum = remainder; // 上一次循环计算的进位
        if (i >= 0) sum += a.charAt(i) - '0'; // 把最后每次循环的最后一位数加给sum
        if (j >= 0) sum += b.charAt(j) - '0';
        sb.append(sum % 2); // %2   二进制遇二进 1
        remainder = sum / 2; // 如果除2 有余数 用remainder接收进位
        i--; j--;
    }
    if (remainder != 0) { // 当循环走完  还有一个进位  就把进位添加到sb中
        sb.append(remainder);
    }
    return sb.reverse().toString();// 反向输出
}

70、爬楼梯

其实就是一个斐波那契数
举个例子: 假设你只差最后一步就走到第10级台阶,这时候分为两种情况,9-10或8-10走一步或两步 ,既然想要走到第10级,那最后一步必然是从8或9开始,那么如果已知0-9有X种走法,0-8有Y种走法,那么0-10就有 X + Y种走法
这个时候把问题反过来想,
当走到1级台阶的时候 只有1种走法 1
当走到2级台阶的时候有2种走法 11 2
根据上面的推断 F(n) = F(n-1) + F(n-2);
那三级台阶的走法就是 1 + 2 等于3种
四级台阶的走法就是 2 + 3 等于5种 以此类推

public int climbStairs(int n) {
    if (n <= 1) return 1;
    int oneStep = 1, twoStep = 1, res = 0;
    for (int i = 2; i <= n; i++){
        res = oneStep + twoStep;
        twoStep = oneStep;
        oneStep = res;
    }
    return res;
}

方法二 :递归解法 不推荐使用 时间复杂度近似O(2^n)

if (n <= 2) { // 如果是只有一级台阶 只有一种方式  如果有两级台阶有2种方式,11 2
    return n;
}else{
    return climbStairs(n -1) + climbStairs2(n - 2);
}

83、删除排序列表种的重复元素

这题超简单,,,
如果当前值和它的next值相等 就让它的next直接指向 next的next

public static ListNode deleteDuplicates(ListNode head) {
    if (head == null || head.next == null) return head;
    ListNode temp = head;
    while(temp != null && temp.next != null){
        if (temp.val == temp.next.val){
            temp.next = temp.next.next; 
        }else{
            temp = temp.next;
        }
    }
    return head;
}

88、合并两个有序数组

因为nums1和nums2本身就是有序的,所有就可以直接从最后开始比较 谁大就取谁 然后–
最后因为是把两个数组合并到nums1 所有如果 j 小于0了 nums1剩下的不用管,如果i小于0了就把nums[j]剩下的放在数组前面

public void merge(int[] nums1, int m, int[] nums2, int n) {
    int i = m - 1;
    int j = n - 1;
    int k = m + n - 1;
    while (i >= 0 && j >= 0){
        nums1[k--] = nums1[i] >= nums2[j] ? nums1[i--] : nums2[j--];
    }
    while (j >= 0) {
        nums1[k--] = nums2[j--];
    }
}

100、相同的树

当两个树都为空的时候 表示他们相等
当有一个树为空的时候 不相等
当前节点的值不相等 返回false
最后递归 把两个树的左子树比较,把两个树的右子树进行比较

public boolean isSameTree(TreeNode p, TreeNode q) {
    if (p == null && q == null) return true;
    if (p == null || q == null) return false;
    if (p.val != q.val) return false;
    return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}

101、对称二叉树

**思路:**t1的左子树等于t2的右子树
t1的右子树 等于t2的左子树

public boolean isSymmetric(TreeNode root) {
    return isMirror(root, root);
}
public boolean isMirror(TreeNode t1, TreeNode t2) {
    if (t1 == null && t2 == null) return true;
    if (t1 == null || t2 == null) return false;
    return (t1.val == t2.val)
            && isMirror(t1.right, t2.left)
            && isMirror(t1.left, t2.right);
}