zoukankan      html  css  js  c++  java
  • Java 旋转数组查找旋转点和任意元素(元素可重复)

    public class Test {
        // 已知数组A是由有序数组B(数组B未知)向右移动n(0<=n<=B.length)位得到
        // 例如 A = {4, 5, 1, 2, 3} 由 B = {1, 2, 3, 4, 5} 向右移动2位得到
        // 求在数组A中搜索元素x
    
        private static int search(int[] a, int h, int t, int x) {
            if (h > t) return -1;
            int result = -1;
            int mid = (h + t) / 2;
            if (a[mid] == x) return mid;
            if (a[h] == a[t] && a[h] == a[mid]) {
                // 这种情况无法判断哪边是递增,那边是旋转数组,如下
                // a = {5, X, 5, X, 5}
                // a = {5, 5, 5, 6, 5}
                // a = {5, 6, 5, 5, 5}
                result = search(a, h, mid - 1, x);
                if (result == -1) result = search(a, mid + 1, t, x);
            } else if (a[h] < a[t]) {
                result = binarySearch(a, h, t, x);
            } else {    // a[h] > a[t] || ( a[h] == a[t] && a[h] != a[mid] )
                if (a[mid] >= a[h]) {
                    // a[h]~a[mid]为递增,a[mid+1]~a[t]为旋转数组
                    result = x >= a[h] ? binarySearch(a, h, mid - 1, x) : search(a, mid + 1, t, x);
                } else {
                    // a[h]~a[mid]为旋转数组,a[mid+1]~a[t]为递增
                    result = x >= a[mid + 1] ? binarySearch(a, mid + 1, t, x) : search(a, h, mid - 1, x);
                }
            }
            return result;
        }
    
        // 第二种方法,先找出数组移位的位数,然后判断应该在哪一段进行二分查找
        private static int getMoveStep(int[] a, int h, int t) {
            if (h >= t) return 0;
            int low = h;
            int high = t;
            int mid = (low + high) / 2;
            int step = 0;
            if (a[low] == a[high]) {
                // 这是一种无法判断哪边是递增序列的情况
                step = getMoveStep(a, h, mid - 1);
                if (step == 0) step = getMoveStep(a, mid + 1, t);
            } else {
                while (a[low] > a[high]) {
                    mid = (low + high) / 2;
                    if (a[mid] >= a[low]) {
                        // 递增序列在mid左边
                        step = low = mid + 1;
                    } else {
                        // 递增序列在mid右边
                        high = mid - 1;
                    }
                }
            }
            return step;
        }
        
        // 利用y移位次数查找
        private static int searchByMove(int[] a, int x) {
            int result;
            int step = getMoveStep(a, 0, a.length - 1);
            if (step != 0) {
                result = x > a[0] ? binarySearch(a, 0, step - 1, x) : binarySearch(a, step, a.length - 1, x);
            } else {
                result = binarySearch(a, 0, a.length - 1, x);
            }
            return result;
        }
    
        private static int binarySearch(int[] a, int h, int t, int x) {
            int low = h;
            int high = t;
            int mid;
            while (low <= high) {
                mid = (low + high) / 2;
                if (a[mid] == x) {
                    return mid;
                } else if (a[mid] < x) {
                    low = mid + 1;
                } else {
                    high = mid - 1;
                }
            }
            return -1;
        }
    
        public static void main(String[] args) {
            int[] a = {4, 5, 1, 2, 3};
            int[] b = {5, 5, 5, 7, 5};
            int[] c = {5, 3, 5, 5, 5};
            int[] d = {5, 5, 3, 4, 5, 5, 5};
            int[] e = {5, 5, 5, 5, 5};
            int[] f = {1, 2, 3, 4, 5};
            System.out.println(search(a, 0, a.length - 1, 1));
            System.out.println(search(b, 0, b.length - 1, 7));
            System.out.println(search(c, 0, c.length - 1, 3));
            System.out.println(search(d, 0, d.length - 1, 3));
            System.out.println(search(e, 0, e.length - 1, 3));
            System.out.println(search(f, 0, f.length - 1, 2));
            System.out.println();
            System.out.println(searchByMove(a, 1));
            System.out.println(searchByMove(b, 7));
            System.out.println(searchByMove(c, 3));
            System.out.println(searchByMove(d, 3));
            System.out.println(searchByMove(e, 3));
            System.out.println(searchByMove(f, 2));
        }
    }
  • 相关阅读:
    'IDataObject': ambiguous symbol的解决方法
    捕获windows系统的sleep或hibernate状态
    CallingConvention理解
    Exception from HRESULT: 0x8001010D (RPC_E_CANTCALLOUT_ININPUTSYNCCALL))
    .Net Managed C++如何获取当前线程id和当前进程id
    div垂直居中于div中
    父级是relative,子级为absolute的情况下,子级宽度自适应
    background-img高度固定,图片自适应
    如何让两个input紧挨着.
    C# 调用百度短链接api
  • 原文地址:https://www.cnblogs.com/zemliu/p/2740775.html
Copyright © 2011-2022 走看看