LeetCode 简单难度_第二周总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_21586317/article/details/81785024

21.合并两个有序链表

将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的

示例:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4

解决方案


方法一: 普通方法

private static ListNode mergeTwoLists(ListNode l1, ListNode l2) {
    if (l1 == null && l2 == null) {
        return null;
    }
    if (l1 == null) {
        return l2;
    }
    if (l2 == null) {
        return l1;
    }
    ListNode head = new ListNode(0);
    ListNode index = head;
    while (l1 != null && l2 != null) {
        if (l1.val < l2.val) {
            head.next = l1;
            l1 = l1.next;
        } else {
            head.next = l2;
            l2 = l2.next;
        }
        head = head.next;
    }
    if (l1 == null) {
        head.next = l2;
    }
    if (l2 == null) {
        head.next = l1;
    }
    return index.next;
}

方法二:递归

private static ListNode mergeTwoLists(ListNode l1, ListNode l2) {
    if (l1 == null && l2 == null) {
        return null;
    }
    if (l1 == null) {
        return l2;
    }
    if (l2 == null) {
        return l1;
    }
    ListNode head;
    if (l1.val < l2.val) {
        head = l1;
        head.next = mergeTwoLists(l1.next, l2);
    } else {
        head = l2;
        head.next = mergeTwoLists(l1, l2.next);
    }
    return head;
}

26. 删除排序数组中的重复项

给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度

不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成

示例 1:
给定数组 nums = [1,1,2],
函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2

示例 2:
给定 nums = [0,0,1,1,1,2,2,3,3,4],
函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4

方法:双指针法

private static int removeDuplicates(int[] nums) {
    if (nums.length == 0) return 0;
    int i = 0;
    for (int j = 1; j < nums.length; j++) {
        // 跳过重复的项
        if (nums[j] != nums[i]) {
            i++;
            nums[i] = nums[j];
        }
    }
    return i + 1;
}

复杂度分析
时间复杂度:O(n)
空间复杂度:O(1)


27. 移除元素

给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

示例 1:
给定 nums = [3,2,2,3], val = 3,
函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2
你不需要考虑数组中超出新长度后面的元素

示例 2:
给定 nums = [0,1,2,2,3,0,4,2], val = 2
函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4

解决方案


方法一:双指针
两个指针 i 和 j,其中 i 是慢指针,j 是快指针

privare static int removeElement(int[] nums, int val) {
    int i = 0;
    for (int j = 0; j < nums.length; j++) {
        if (nums[j] != val) {
            nums[i] = nums[j];
            i++;
        }
    }
    return i;
}

复杂度分析
时间复杂度:O(n),假设数组总共有 n 个元素,i 和 j 至少遍历 2n 步
空间复杂度:O(1)

方法二:双指针 —— 当要删除的元素很少时
遇到 nums[i] = val 时,我们可以将当前元素与最后一个元素进行交换,并释放最后一个元素。这实际上使数组的大小减少了 1

请注意,被交换的最后一个元素可能是您想要移除的值。但是不要担心,在下一次迭代中,我们仍然会检查这个元素

privare static int removeElement(int[] nums, int val) {
    int i = 0;
    int n = nums.length;
    while (i < n) {
        if (nums[i] == val) {
            nums[i] = nums[n - 1];
            // reduce array size by one
            n--;
        } else {
            i++;
        }
    }
    return n;
}

复杂度分析
时间复杂度:O(n),i 和 j 最多遍历 n 步
空间复杂度:O(1)


28. 实现 strStr()

给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。

示例 1:
输入: haystack = “hello”, needle = “ll”
输出: 2

示例 2:
输入: haystack = “aaaaa”, needle = “bba”
输出: -1

说明:
当 needle 是空字符串时,我们应当返回 0

自己写的

private static int strStr(String haystack, String needle) {
    if (haystack == null || needle == null) {
        return -1;
    }
    if (haystack.length() == 0) {
        if (needle.length() != 0) {
            return -1;
        }
    } else {
        if (needle.length() == 0) {
            return 0;
        }
    }
    if (haystack.length() < needle.length()) {
        return -1;
    }
    if (haystack.equals(needle)) {
        return 0;
    }
    char[] hs = haystack.toCharArray();
    char[] ns = needle.toCharArray();
    int k = 0;
    for (int i = 0; i < hs.length; i++) {
        if (hs[i] == ns[0]) {
            for (int j = 0; j < ns.length; j++) {
                if (j + i == hs.length) {
                    return -1;
                }
                if (hs[j + i] == ns[j]) {
                    k++;
                } else {
                    k = 0;
                    break;
                }
                if (k == ns.length) {
                    return i;
                }
            }
        }
    }
    return -1;
}

35. 搜索插入位置

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置

你可以假设数组中无重复元素

示例 1:
输入: [1,3,5,6], 5
输出: 2

示例 2:
输入: [1,3,5,6], 2
输出: 1

示例 3:
输入: [1,3,5,6], 7
输出: 4

示例 4:
输入: [1,3,5,6], 0
输出: 0

private static int searchInsert(int[] nums, int target) {
    if (nums == null) {
        throw new IllegalArgumentException("your nums is null");
    }
    if (target <= nums[0]) {
        return 0;
    } else if (target == nums[nums.length - 1]) {
        return nums.length - 1;
    } else if (target > nums[nums.length - 1]) {
        return nums.length;
    }
    return getMiddle(nums, 0, nums.length, target);
}

// 二分查找 + 递归:不断缩小范围,最终确定目标值的索引
private static int getMiddle(int[] nums, int start, int end, int target) {
    int mid = (start + end) / 2;
    if (start == mid) {
        return mid + 1;
    } else if (start == end) {
        return end + 1;
    }
    if (nums[mid] < target) {
        start = mid;
    } else if (nums[mid] > target) {
        end = mid;
    } else {
        return mid;
    }
    return getMiddle(nums, start, end, target);
}

猜你喜欢

转载自blog.csdn.net/qq_21586317/article/details/81785024