64x的平方根 力扣83删除排序链表中的重复元素 88 合并两个有序数组

64x的平方根

实现 int sqrt(int x) 函数。

计算并返回 x 的平方根,其中 x 是非负整数。

由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。

示例 1:

输入: 4
输出: 2
示例 2:

输入: 8
输出: 2
说明: 8 的平方根是 2.82842…,
由于返回类型是整数,小数部分将被舍去。

使用内置函数:注意从double转为int的操作格式 
class Solution {
    
    
    public int mySqrt(int x) {
    
    
        return (int)Math.sqrt(x);
    }
}

方法二:二分查找
由于 xx 平方根的整数部分 \textit{ans}ans 是满足 k^2 \leq xk
2
≤x 的最大 kk 值,因此我们可以对 kk 进行二分查找,从而得到答案。

二分查找的下界为 00,上界可以粗略地设定为 xx。在二分查找的每一步中,我们只需要比较中间元素 \textit{mid}mid 的平方与 xx 的大小关系,并通过比较的结果调整上下界的范围。由于我们所有的运算都是整数运算,不会存在误差,因此在得到最终的答案 \textit{ans}ans 后,也就不需要再去尝试 \textit{ans} + 1ans+1 了。

思路,二分查找的下界0 上界x,每一步比较中间元素的平方和x的大小
根据结果调整上界和下界的范围。
注意  long的使用 mid不是最终结果是要令l = mid+1;
class Solution {
    
    
    public int mySqrt(int x) {
    
    
        int l = 0, r = x, ans = -1;
        while (l <= r) {
    
    
            int mid = l + (r - l) / 2;
            if ((long) mid * mid <= x) {
    
    
                ans = mid;
                l = mid + 1;
            } else {
    
    
                r = mid - 1;
            }
        }
        return ans;
    }
}


力扣83删除排序链表中的重复元素

给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。

示例 1:

输入: 1->1->2
输出: 1->2
示例 2:

输入: 1->1->2->3->3
输出: 1->2->3

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    
    
    public ListNode deleteDuplicates(ListNode head) {
    
    
        ListNode current = head;
        while (current != null && current.next != null) {
    
    
            if (current.next.val == current.val) {
    
    
                current.next = current.next.next;
            } else {
    
    
                current = current.next;
            }
        }
        return head;
    }
}

88 合并两个有序数组

给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。

初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。你可以假设 nums1 有足够的空间(空间大小等于 m + n)来保存 nums2 中的元素。

示例 1:

输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
示例 2:

输入:nums1 = [1], m = 1, nums2 = [], n = 0
输出:[1]

在这里插入图片描述

复杂度 O(m+n)log(m+n)
思路  先合并两个数组,nums2是原数组,0:表示从0索引开始,nums1:目标数组  m:目标数组开始插入的位置  n:n是数组2的长度
class Solution {
    
    
  public void merge(int[] nums1, int m, int[] nums2, int n) {
    
    
    System.arraycopy(nums2, 0, nums1, m, n);
    Arrays.sort(nums1);
  }
}
解题方案
思路
	1、标签:从后向前数组遍历
	2、因为 nums1 的空间都集中在后面,所以从后向前处理排序的数据会更好,节省空间,一边遍历一边将值填充进去
	3、设置指针 len1 和 len2 分别指向 nums1 和 nums2 的有数字尾部,从尾部值开始比较遍历,同时设置指针 len 指向 nums1 的最末尾,每次遍历比较值大小之后,则进行填充
	4、当 len1<0 时遍历结束,此时 nums2 中海油数据未拷贝完全,将其直接拷贝到 nums1 的前面,最后得到结果数组
时间复杂度:O(m+n)O(m+n)

代码
class Solution {
    
    
    public void merge(int[] nums1, int m, int[] nums2, int n) {
    
    
        int len1 = m - 1;
        int len2 = n - 1;
        int len = m + n - 1;
        while(len1 >= 0 && len2 >= 0) {
    
    
            // 注意--符号在后面,表示先进行计算再减1,这种缩写缩短了代码
            nums1[len--] = nums1[len1] > nums2[len2] ? nums1[len1--] : nums2[len2--];
        }
        // 表示将nums2数组从下标0位置开始,拷贝到nums1数组中,从下标0位置开始,长度为len2+1
        System.arraycopy(nums2, 0, nums1, 0, len2 + 1);
    }
}
思路:三个指针,分别指向数组1:p1 数组2p2 数组1扩展从后到前的指针p
从后向前遍历,p1>p2,将p1索引处的值放入最后
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);
  }
}


在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_40310710/article/details/112556516