leetcode 540 - 有序数组中的单一元素

题目: https://leetcode.cn/problems/single-element-in-a-sorted-array/
程序目录结构如下,
程序目录结构
CMakeLists.txt

cmake_minimum_required(VERSION 2.6)

project(single_element_in_a_sorted_arr)
set(CMAKE_CXX_STANDARD 20)
add_definitions(-g)

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../include)
string(REPLACE ".cpp" "" file "main.cpp")
add_executable(${file}  "main.cpp")

main.cpp

#include "printer/printer.hpp"

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;

class Solution {
public:
    // 暴力法,时间复杂度为 O(n)
    int singleNonDuplicate_1(vector<int>& nums) {
        if(nums.size() == 1) return nums[0];
        int i {0};
        for(; i+2 < nums.size(); i+=2) {
            if(nums[i] != nums[i+1]) return nums[i];
        }

        // 此处最后一个元素是单一元素
        // 使用gdb进行调试就可以知道 以下事实
        // i = 2 nums.size() = 3
        // i = nums.size() - 1
        // 注意 i 已经加过2,变成 nums.size() - 1了,才会退出循环
        if(i == nums.size() - 1) {
            return *nums.rbegin();
        }
        return -1;
    }

    // 二分法,时间复杂度为O(lg(n))
    int singleNonDuplicate(vector<int>& nums) {
        int l {0}, r{(int)nums.size() - 1};
        // 二分法查找元素,这个标记位比较有意思
        while(l < r) {
            // 求元素中位
            auto mid = (l + r) >> 1;
            // 有两种情况,表示单一非重复元素不在前半部分
            // mid为偶数, a[mid] = a[mid + 1]
            // mid为奇数, a[mid - 1] = a[mid]
            // 这两种情况都可以概括为:
            // a[mid] = a[mid ^ 1], 所以不用区分奇偶 了
            // 当mid为偶数时 mid ^ 1 = mid + 1
            // 当mid为奇数时 mid ^ 1 = mid - 1
            // 所以上面一句就代表了两种情况
            // 另一个值的注意的点就是mid和它相邻的点相等了,说明mid位置的元素重复了,所以在
            // (m,r] 区间继续寻找
            if(nums[mid] == nums[mid ^ 1]) {
                l = mid + 1;
            } else {
                // 这里代表mid和它相邻的元素不等,说明不重复的元素在前半部分。
                // 因为mid和相邻的元素不等,所以有可能是单一元素,去
                // [l, mid] 区间寻找
                r = mid;
            }
        }
        return nums[l];
    }
};

auto main(int argc, char** argv) -> int {
    Solution s;
    vector<int> nums{1, 1, 2};
    auto res = s.singleNonDuplicate_1(nums);
    cout << res << "\n";
    return EXIT_SUCCESS;
}

程序输出结果如下,
程序输出结果如下

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值