C C++最新【剑指Offer】二分法例题_数据结构二分法简答题(1),2024年最新意外收获字节跳动内部资料

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

<2>二维数组中的查找

题目链接
描述:

在一个二维数组array中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
[
[1,2,8,9],
[2,4,9,12],
[4,7,10,13],
[6,8,11,15]
]
给定 target = 7,返回 true。
给定 target = 3,返回 false。

数据范围:矩阵的长宽满足 0≤n,m≤500,矩阵中的值满足0≤val≤10^9
进阶:空间复杂度 O(1)O(1) ,时间复杂度 O(n+m)O(n+m)

示例1

输入:7,[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]]
返回值:true
说明:存在7,返回true

示例2:

输入:1,[[2]]
返回值:false

示例3

输入:3,[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]]
返回值:false
说明:不存在3,返回false

① 线性搜索

最简单的方法就是暴力遍历,没有用到二维数组的递增性质。
通过规律发现左下角所在元素的所在行最小,所在列最大,那么如果target小于所在元素,就让行--,否则就让列++
在这里插入图片描述

bool Find(int target, int\*\* array, int arrayRowLen, int\* arrayColLen ) {
    // write code here
    int row = arrayRowLen - 1, col = 0;
    while(row <= arrayRowLen - 1 && row >= 0 && col <= \*arrayColLen - 1 && col >= 0)
    {
        if(array[row][col] == target)
        {
            return true;
        }
        else
        {
            if(array[row][col] < target)
            {
                col++;
            }
            else
            {
                row--;
            }
        }
    }
    return false;
}

② 逐行二分

因为每一行都是有序递增的,所以每一行都能用二分
在这里插入图片描述

bool binary\_search(int\* arr, int k, int target)
{
    int left = 0, right = k - 1;
    while (left <= right)
    {
        int mid = (right + left) / 2;
        if (arr[mid] == target)
        {
            return true;
        }
        else if (arr[mid] > target)
        {
            right = mid - 1;
        }
        else
        {
            left = mid + 1;
        }
    }
    return false;
}



bool Find(int target, int\*\* array, int arrayRowLen, int\* arrayColLen) {
    // write code here
    for (int i = 0; i < arrayRowLen; i++)
    {
        if (binary\_search(array[i], \*arrayColLen, target))
        {
            return true;
        }
    }
   /\*while (arrayRowLen--)
 {
 if (binary\_search(\*array, \*arrayColLen, target))
 {
 return true;
 }
 array++;
 }\*/
    return false;
}

<3>旋转数组的最小数字

题目链接

描述:

有一个长度为 n 的非降序数组,比如[1,2,3,4,5],将它进行旋转,即把一个数组最开始的若干个元素搬到数组的末尾,变成一个旋转数组,比如变成了[3,4,5,1,2],或者[4,5,1,2,3]这样的。请问,给定这样一个旋转数组,求数组中的最小值。

数据范围:1≤n≤10000,数组中任意元素的值:0≤val≤10000
要求:空间复杂度:O(1)O(1) ,时间复杂度:O(logn)O(logn)

示例1:

输入:[3,4,5,1,2]
返回值:1

示例2:

输入:[3,100,200,3]
返回值:3

思路分析:
这道题其实是二分法的变形,旋转点左边的元素都单调递增且都大于旋转点右边单调递增的元素。
我们的目的是找到旋转点也就是最小的元素,我们可以定义左left、右right指针让他们相遇在旋转点:
arr[mid] > arr[right]
说明mid一定在左递增区间,为了使left移动到旋转点就需要缩小区间,left = mid + 1
arr[mid] < arr[right]
说明mid一定在右递增区间,为了使right移动到旋转点就需要缩小区间,right = mid
但是也有相同元素的情况,例如:{1,0,1,1,1}
这样就无法判断mid在哪个区间了。
那么就让right--,这里不能让left++,因为我们是跟最右边的元素比较,旋转点一定在mid左边。

int minNumberInRotateArray(int\* arr, int sz ) {
    // write code here
    if(sz == 0)
    {
        return 0;
    }
    int left = 0, right = sz - 1;
    while(left < right)
    {
        int mid = (left + right) / 2;
        if(arr[mid] > arr[right])
        {


![img](https://img-blog.csdnimg.cn/img_convert/11b7109f70bbe1d6eb02d1c5864f306c.png)
![img](https://img-blog.csdnimg.cn/img_convert/637d7b75141f1f5134f3da641b9677a9.png)

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.youkuaiyun.com/topics/618668825)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

1715725816532)]

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.youkuaiyun.com/topics/618668825)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值