Bia布刷题日记 LC-15 三数之和

Leecode 540 有序数组中的单一元素

算法描述:

540.有序数组中的单一元素给你一个仅由整数组成的有序数组,其中每个元素都会出现两次,唯有一个数只会出现一次。
请你找出并返回只出现一次的那个数。
你设计的解决方案必须满足 O(log n)时间复杂度和 O(1) 空间复杂度。

示例 1:

输入: nums = [1,1,2,3,3,4,4,8,8]
输出: 2

示例 2:

输入: nums = [3,3,7,7,10,11,11]
输出: 10

题目链接:点我跳转题目

算法思路:

思路一:

遍历,从头开始遍历数组,步长设置为2,逐个判断当前元素和后一元素是否相同,若不同,则证明前一元素为单一元素,相同则继续向后遍历,一直遍历到数组最后。

思路二:

首先是不含有单位元素的数组及其对应的下标,第一个重复元素的下标都为偶数,第二个重复元素的下标都为奇数
1 1 3 3 4 4 8 8
0 1 2 3 4 5 6 7

然后是含有单位元素的数组及其对应的下标记,在单位数左边,依然遵循刚才的规则,在单位数右边,由于加入了单位数
第一个重复元素的下标向后加了一位变为了奇数,第二个重复元素的下标变为了偶数
1 1 2 3 3 4 4 8 8
0 1 2 3 4 5 6 7 8

由于存在这样的二段性,可以对当前二分点mid的奇偶性进行分情况讨论:

  1. mid为偶数
    正常情况下偶数下标的值会和下一值相同,所以如果当前值满足此条件,则证明该mid值之前没有插入单一元素。更新左右边界。
  2. mid为奇数
    正常情况下奇数下标的值会和上一个值相同,如果满足该条件,则可以确保mid之前没有插入单一元素,更新左右边界。

算法代码:

方法一代码:

    //方法1:遍历
    public static int singleNonDuplicate(int[] nums) {
        

        int len = nums.length;
        for (int i = 0;i < len-1;i+=2){
            if (nums[i] != nums[i + 1]){
                return nums[i];
            }
        }
        return nums[len-1];


    }

时间复杂度:O(N)
空间复杂度:O(1)

方法二代码:

//方法2:二段法
    public static int singleNonDuplicate(int[] nums) {


        int n = nums.length;
        int l = 0, r = n - 1;

        while (l < r) {

            int mid = l + r >> 1;
            //mid为偶数
            if (mid % 2 == 0) {
                if (mid + 1 < n && nums[mid] == nums[mid + 1]) {
                    //左侧为没有插入单个元素的数组,更新左边界
                    l = mid + 1;
                } else {
                    //右侧为没有插入单个元素的数组,更新右边界
                    r = mid;
                }
            } else {
                //mid为奇数
                if (mid - 1 >= 0 && nums[mid] == nums[mid - 1]) {
                    //左侧为没有插入单个元素的数组,更新左边界
                    l = mid + 1;
                } else {
                    //右侧为没有插入单个元素的数组,更新右边界
                    r = mid;
                }


            }


        }


        return nums[r];
}

时间复杂度:O(logN)
空间复杂度:O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值