📜  C++程序在K左旋转后查找数组的第M个元素(1)

📅  最后修改于: 2023-12-03 14:59:52.210000             🧑  作者: Mango

C++程序在K左旋转后查找数组的第M个元素

旋转数组是指把一个数组的最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。例如,数组 1 2 3 4 5 6 7 经过三次旋转后变为 4 5 6 7 1 2 3

本题的重点是在旋转后的数组中查找第M个元素。

解题思路

使用二分查找可以在O(logN)的时间复杂度内完成查找。二分查找其实就是将搜索区间一分为二,然后判断目标值在哪一部分,并继续对那一部分继续进行搜索。具体步骤如下:

  1. 如果数组长度为1,直接返回该元素;如果数组长度为2,判断是否与目标元素相等,相等则返回该元素,否则返回-1。
  2. 如果数组首元素小于末尾元素,则数组有序,直接使用二分查找进行查找。
  3. 如果数组首元素等于末尾元素,则无法判断哪一部分是有序的。这个时候只能暴力查找。
  4. 如果数组首元素大于末尾元素,则判断当前元素是否大于等于首元素,从而判断哪一部分是有序的。
代码实现
int binarySearch(int arr[], int start, int end, int target) {
    while (start <= end) {
        int mid = start + (end - start) / 2;
        if (arr[mid] == target) {
            return mid;
        } else if (arr[mid] < target) {
            start = mid + 1;
        } else {
            end = mid - 1;
        }
    }
    return -1;
}

int findElement(int arr[], int n, int k, int m) {
    if (n == 0) {
        return -1;
    } else if (n == 1) {
        return arr[0];
    } else if (n == 2) {
        if (arr[0] == m) {
            return arr[0];
        } else if (arr[1] == m) {
            return arr[1];
        } else {
            return -1;
        }
    }

    int first = 0, last = n - 1;
    while (first < last) {
        int mid = first + (last - first) / 2;

        if (arr[first] < arr[last]) {
            // 数组有序
            if (m == arr[mid]) {
                return mid;
            } else if (m < arr[mid]) {
                last = mid - 1;
            } else {
                first = mid + 1;
            }
        } else if (arr[first] == arr[last]) {
            // 无法判断哪一部分是有序的
            for (int i = first; i <= last; i++) {
                if (arr[i] == m) {
                    return i;
                }
            }
            return -1;
        } else {
            // 左半部分有序
            if (arr[mid] >= arr[first]) {
                if (m == arr[mid]) {
                    return mid;
                } else if (m >= arr[first] && m < arr[mid]) {
                    last = mid - 1;
                } else {
                    first = mid + 1;
                }
            } else {
                // 右半部分有序
                if (m == arr[mid]) {
                    return mid;
                } else if (m > arr[mid] && m <= arr[last]) {
                    first = mid + 1;
                } else {
                    last = mid - 1;
                }
            }
        }
    }
    return -1;
}
代码说明

第一个函数 binarySearch 是二分查找函数,可以用来在有序的数组中查找目标元素并返回其下标。第二个函数 findElement 是在旋转数组中查找第M个元素的函数。

总结

本题重点在于如何在旋转后的数组中查找目标元素。通过使用二分查找可以做到时间复杂度为 O(logN),具有较高的运行效率。当然,在有些情况下二分查找并不适合,比如数组中有重复元素等情况,这时候就需要选择其他的查找方法。