剑指offer 刷题4 数组

本文详细介绍了《剑指Offer》中关于数组的操作题目,包括二维数组中的查找、旋转数组的最小数字、调整数组顺序、连续子数组最大和及数组中的重复数字。通过递归、二分法、插入排序等方法进行解题,并提供了关键思路和参考链接。
摘要由CSDN通过智能技术生成

目录

二维数组中的查找3/6

旋转数组的最小数字

调整数组顺序

 连续子数组最大和3/7

数组中的重复数字


二维数组中的查找3/6

参考:https://www.cnblogs.com/silentteller/p/11762414.html(右上角查找)

参考:https://www.nowcoder.com/questionTerminal/abc3fe2ce8e146608e868a70efebf62e?f=discussion(左下角查找)

 思路:

采用右上角元素进行比较:

1 行rows = array.size();列cols = array.size(); 右上角元素下标array[0][cols - 1]

2 i 扫描行,i <rows; j扫描列, j>=0

3 当target>当前值,向下查找;i++

   当target <当前值,向左查找;j--

直至找到/扫描完,退出循环

【查找】

class Solution {
public:
    bool Find(int target, vector<vector<int> > array) {
        // array是二维数组,这里没做判空操作
        int rows = array.size();//行
        int cols = array[0].size();//列
        int i=0,j=cols-1;//右上角角元素坐标
        while(i<rows && j>=0){//使其不超出数组范围
            if(target>array[i][j])
                i++;//查找的元素较小,往下找
            else if(target<array[i][j])
                j--;//查找元素较大,往左找
            else
                return true;//出口A,找到
        }
        return false;//出口B,没找到
    }
};

旋转数组的最小数字

【递归】和【二分法】

二分法思路:

1 左指针l = 0,右指针r = size-1;mid = l + (r - l)/2;

2 (以下用l代称左指针指向的数字,r,mid同理)

    因为原序列是非递减(含有重复数字),所以最小值可能出现在右边(不绝对,例如不旋转时候,最小值在最左边),所以这里选择mid和r进行比较。

   如果mid > r,说明左边有序非递减,如{3412}或{333111},那么最小值在右侧,要去右边的半段中找,l = mid + 1;

   如果mid < r,说明右边有序非递减,如{4123}或{311133},但是mid可能就是最小值,比如{4123},要注意这里的边界。

           特殊情况:右边非递减序列的起点可能是现在的mid,也可能在[l, mid]区间内,所以 r = mid;相当于去[l,mid]中找最小                 值,因为 此时的mid是右边最小值。

   如果mid = r,出现重复元素,r--

3 当l < r 的时候一直做2的循环

    跳出循环条件: l = r,这个时候l和r指向同一个元素,不用再进行比较

4 返回r指针指向的数组的值

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        int left = 0, right = (int)rotateArray.size() - 1;
        while(left < right){//注意小于号,当左右相当,即同一元素,不用比较大小
            int mid = left + (right - left) / 2;
            if(rotateArray[mid] > rotateArray[right]) left = mid + 1;//左半段有序,比如{3423}
            else if(rotateArray[mid] < rotateArray[right]) right = mid;//右半段有序,但是mid可能就是最小值,比如{3123},要注意这里的边界
            else right--;//删除重复
        }
        return rotateArray[right];
    }
};

递归方法:

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        if(rotateArray.empty())
            return 0;
        return find(rotateArray, 0, rotateArray.size()-1);
    }
    int find(vector<int> &nums, int l, int r){
        if(nums[l] < nums[r] || l == r)//【易错】
            return nums[l];
        int mid = l + (r - l) / 2;
        return min(find(nums, l, mid), find(num
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值