算法leetcode|81. 搜索旋转排序数组 II(rust重拳出击)

这篇具有很好参考价值的文章主要介绍了算法leetcode|81. 搜索旋转排序数组 II(rust重拳出击)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。



81. 搜索旋转排序数组 II:

已知存在一个按非降序排列的整数数组 nums ,数组中的值不必互不相同。

在传递给函数之前,nums 在预先未知的某个下标 k0 <= k < nums.length)上进行了 旋转 ,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,4,4,5,6,6,7] 在下标 5 处经旋转后可能变为 [4,5,6,6,7,0,1,2,4,4]

给你 旋转后 的数组 nums 和一个整数 target ,请你编写一个函数来判断给定的目标值是否存在于数组中。如果 nums 中存在这个目标值 target ,则返回 true ,否则返回 false

你必须尽可能减少整个操作步骤。

样例 1:

输入:
	
	nums = [2,5,6,0,0,1,2], target = 0
	
输出:
	
	true

样例 2:

输入:
	
	nums = [2,5,6,0,0,1,2], target = 3
	
输出:
	
	false

提示:

  • 1 <= nums.length <= 5000
  • -104 <= nums[i] <= 104
  • 题目数据保证 nums 在预先未知的某个下标上进行了旋转
  • -104 <= target <= 104

进阶:

  • 这是 搜索旋转排序数组 的延伸题目,本题中的 nums 可能包含重复元素。
  • 这会影响到程序的时间复杂度吗?会有怎样的影响,为什么?

分析:

  • 面对这道算法题目,二当家的再次陷入了沉思。
  • 如果没有旋转,那肯定使用二分查找,二分查找可以在每一次循环遍历都排除一半的数据,效率非常高。
  • 要使用二分查找,数组必须是有序的,但是数组已经被旋转了,所以并不是完全有序,但也并不是完全没有办法。
  • 一般的二分是每次比较中间元素,然后判断元素是否相等,如果不相等再看元素应该在左半部分,还是右半部分,由此排除一半的元素,再继续在另一部分中重复这样的逻辑。
  • 我们可以使用变形的二分查找,可以想到,有序数组旋转后,从中分成两部分,一定有一部分是有序的,而另一部分也是部分有序,但是头一定不小于尾,所以我们可以先判断哪一部分有序,然后再看目标数字是否在有序那部分当中,来决定改变左边界,还是右边界,这样便可以达到二分查找的效率。
    算法leetcode|81. 搜索旋转排序数组 II(rust重拳出击),LeetCode力扣算法题目,rust,golang,算法,数据结构,后端,leetcode
  • 由于数组中允许重复元素,那么在某一次查找时,可能会出现中间元素和头尾元素都是相同的情况,这时候就没办法判断哪半部分是有序的,也就不能直接排除一半的元素,但是我们可以将头和尾的元素排除掉。

题解:

rust:

impl Solution {
    pub fn search(nums: Vec<i32>, target: i32) -> bool {
        let n = nums.len();
        if n == 0 {
            return false;
        }
        if n == 1 {
            return nums[0] == target;
        }
        let (mut l, mut r) = (0, n - 1);
        while l <= r {
            let mid = (l + r) >> 1;
            if nums[mid] == target {
                return true;
            }
            if nums[l] == nums[mid] && nums[mid] == nums[r] {
                if r == 0 {
                    // 防止r溢出到非常大
                    return false;
                }
                l += 1;
                r -= 1;
            } else if nums[l] <= nums[mid] {
                if nums[l] <= target && target < nums[mid] {
                    r = mid - 1;
                } else {
                    l = mid + 1;
                }
            } else {
                if nums[mid] < target && target <= nums[n - 1] {
                    l = mid + 1;
                } else {
                    r = mid - 1;
                }
            }
        }
        return false;
    }
}

go:

func search(nums []int, target int) bool {
    n := len(nums)
	if n == 0 {
		return false
	}
	if n == 1 {
		return nums[0] == target
	}
	l, r := 0, n-1
	for l <= r {
		mid := (l + r) >> 1
		if nums[mid] == target {
			return true
		}
		if nums[l] == nums[mid] && nums[mid] == nums[r] {
			l++
			r--
		} else if nums[l] <= nums[mid] {
			if nums[l] <= target && target < nums[mid] {
				r = mid - 1
			} else {
				l = mid + 1
			}
		} else {
			if nums[mid] < target && target <= nums[n-1] {
				l = mid + 1
			} else {
				r = mid - 1
			}
		}
	}
	return false
}

c++:

class Solution {
public:
    bool search(vector<int>& nums, int target) {
        const int n = nums.size();
        if (n == 0) {
            return false;
        }
        if (n == 1) {
            return nums[0] == target;
        }
        int l = 0, r = n - 1;
        while (l <= r) {
            int mid = (l + r) >> 1;
            if (nums[mid] == target) {
                return true;
            }
            if (nums[l] == nums[mid] && nums[mid] == nums[r]) {
                ++l;
                --r;
            } else if (nums[l] <= nums[mid]) {
                if (nums[l] <= target && target < nums[mid]) {
                    r = mid - 1;
                } else {
                    l = mid + 1;
                }
            } else {
                if (nums[mid] < target && target <= nums[n - 1]) {
                    l = mid + 1;
                } else {
                    r = mid - 1;
                }
            }
        }
        return false;
    }
};

python:

class Solution:
    def search(self, nums: List[int], target: int) -> bool:
        if not nums:
            return False

        n = len(nums)
        if n == 1:
            return nums[0] == target

        l, r = 0, n - 1
        while l <= r:
            mid = (l + r) >> 1
            if nums[mid] == target:
                return True
            if nums[l] == nums[mid] and nums[mid] == nums[r]:
                l += 1
                r -= 1
            elif nums[l] <= nums[mid]:
                if nums[l] <= target < nums[mid]:
                    r = mid - 1
                else:
                    l = mid + 1
            else:
                if nums[mid] < target <= nums[n - 1]:
                    l = mid + 1
                else:
                    r = mid - 1

        return False


java:

class Solution {
    public boolean search(int[] nums, int target) {
        final int n = nums.length;
        if (n == 0) {
            return false;
        }
        if (n == 1) {
            return nums[0] == target;
        }
        int l = 0, r = n - 1;
        while (l <= r) {
            int mid = (l + r) / 2;
            if (nums[mid] == target) {
                return true;
            }
            if (nums[l] == nums[mid] && nums[mid] == nums[r]) {
                ++l;
                --r;
            } else if (nums[l] <= nums[mid]) {
                if (nums[l] <= target && target < nums[mid]) {
                    r = mid - 1;
                } else {
                    l = mid + 1;
                }
            } else {
                if (nums[mid] < target && target <= nums[n - 1]) {
                    l = mid + 1;
                } else {
                    r = mid - 1;
                }
            }
        }
        return false;
    }
}

非常感谢你阅读本文~
欢迎【点赞】【收藏】【评论】三连走一波~
放弃不难,但坚持一定很酷~
希望我们大家都能每天进步一点点~
本文由 二当家的白帽子:https://le-yi.blog.csdn.net/ 博客原创~文章来源地址https://www.toymoban.com/news/detail-726679.html


到了这里,关于算法leetcode|81. 搜索旋转排序数组 II(rust重拳出击)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 算法leetcode|48. 旋转图像(rust重拳出击)

    给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。 请不要 使用另一个矩阵来旋转图像。 n == matrix.length == matrix[i].length 1 = n = 20 -1000 = matrix[i][j] = 1000 面对这道算法题目,二当家

    2024年02月01日
    浏览(95)
  • 算法leetcode|90. 子集 II(rust重拳出击)

    给你一个整数数组 nums ,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。 解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。 1 = nums.length = 10 -10 = nums[i] = 10 面对这道算法题目,二当家的再次陷入了沉思。 穷举数组的所有子集,每个

    2024年02月04日
    浏览(43)
  • 算法leetcode|61. 旋转链表(rust重拳出击)

    给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。 链表中节点的数目在范围 [0, 500] 内 -100 = Node.val = 100 0 = k = 2 * 10 9 面对这道算法题目,二当家的再次陷入了沉思。 首先节点向右移动的位置 k 为0,我们什么都不需要做,直接返回原来的链表即可。

    2024年02月13日
    浏览(52)
  • 算法leetcode|47. 全排列 II(rust重拳出击)

    给定一个可包含重复数字的序列 nums , 按任意顺序 返回所有不重复的全排列。 1 = nums.length = 8 -10 = nums[i] = 10 面对这道算法题目,二当家的再次陷入了沉思。 要做全排列,就用递归套娃大法,回溯是大方向。 有重复的数字,又要不重复的排列,去重也是必须的了,最慢的方

    2023年04月26日
    浏览(75)
  • 算法leetcode|45. 跳跃游戏 II(rust重拳出击)

    给定一个长度为 n 的 0 索引整数数组 nums 。初始位置为 nums[0] 。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i + j] 处: 0 = j = nums[i] i + j n 返回到达 nums[n - 1] 的 最小跳跃次数 。生成的测试用例可以到达 nums[n - 1] 。

    2023年04月15日
    浏览(51)
  • 算法leetcode|63. 不同路径 II(rust重拳出击)

    一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。 现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径? 网格中的障碍

    2024年02月16日
    浏览(49)
  • 算法leetcode|59. 螺旋矩阵 II(rust重拳出击)

    给你一个正整数 n ,生成一个包含 1 到 n 2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 1 = n = 20 面对这道算法题目,二当家的再次陷入了沉思。 可以每次循环移动一步,判断移到边界就变换方向,巧用数组可以减少逻辑判断的复杂性。 也可以每次循环

    2024年02月11日
    浏览(44)
  • 算法leetcode|92. 反转链表 II(rust重拳出击)

    给你单链表的头指针 head 和两个整数 left 和 right ,其中 left = right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。 链表中节点数目为 n 1 = n = 500 -500 = Node.val = 500 1 = left = right = n 你可以使用一趟扫描完成反转吗? 将链表分成3部分,即前面不需要反转的部

    2024年02月05日
    浏览(50)
  • 力扣_数组24—搜索旋转排序数组II

    已知存在一个按非降序排列的整数数组 n u m s nums n u m s ,数组中的值不必互不相同。 在传递给函数之前, n u m s nums n u m s 在预先未知的某个下标 k ( 0 = k n u m s . l e n g t h ) k(0 = k nums.length) k ( 0 = k n u m s . l e n g t h ) 上进行了 旋转 ,使数组变为 [ n u m s [ k ] , n u m s [

    2024年01月19日
    浏览(57)
  • 算法leetcode|79. 单词搜索(rust重拳出击)

    给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

    2024年02月09日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包