Ejemplo n.º 1
0
    // 执行用时: 124 ms, 在所有 C# 提交中击败了 25.00% 的用户
    // 内存消耗: 25.1 MB, 在所有 C# 提交中击败了 100.00% 的用户
    public int FindInMountainArray(int target, MountainArray mountainArr)
    {
        int start = 0;
        int end   = mountainArr.Length() - 1;

        while (start < end)
        {
            // Use this approach instead of (start + end) / 2 to avoid overflow.
            int middle = start + (end - start) / 2;

            if (mountainArr.Get(middle) < mountainArr.Get(middle + 1))
            {
                start = middle + 1;
            }
            else
            {
                end = middle - 1;
            }
        }

        int peak = start;

        Console.WriteLine($"peak = {peak}");

        int indexOfTarget = this.BinarySearchMountainArray(mountainArr, target, 0, peak);

        if (indexOfTarget != -1)
        {
            return(indexOfTarget);
        }

        return(this.BinarySearchMountainArray(mountainArr, target, peak + 1, mountainArr.Length() - 1, false));
    }
Ejemplo n.º 2
0
        /// <summary>
        /// Find in Mountain Array (Mine)
        /// </summary>
        /// <param name="target"></param>
        /// <param name="mountainArr"></param>
        /// <returns></returns>
        public static int FindInMountainArray(int target, MountainArray mountainArr)
        {
            int a = 0, b = mountainArr.Length() - 1;
            int peek;

            while (true)
            {
                int curr = (a + b) / 2;
                var(left, currValue, right) = (curr - 1 < 0 ? -1 : mountainArr.Get(curr - 1),
                                               mountainArr.Get(curr),
                                               curr + 1 >= mountainArr.Length() ? mountainArr.Length() : mountainArr.Get(curr + 1));
                if (currValue > left && currValue > right)
                {
                    peek = curr;
                    break;
                }

                if (currValue < right)
                {
                    a = curr + 1;
                }
                else
                {
                    b = curr - 1;
                }
            }

            int res = FindInMountainArrayHelper(target, mountainArr, 0, peek);

            if (res != -1)
            {
                return(res);
            }
            return(FindInMountainArrayHelper(target, mountainArr, peek, mountainArr.Length() - 1, false));
        }
Ejemplo n.º 3
0
    public int FindInMountainArray(int target, MountainArray mountainArr)
    {
        int left  = 0;
        int right = mountainArr.Length() - 1;

        // 先找到峰顶
        while (left < right)
        {
            int mid = left + (right - left) / 2;
            if (mountainArr.Get(mid) <= mountainArr.Get(mid + 1))
            {
                left = mid + 1;
            }
            else
            {
                right = mid;
            }
        }
        // 根据题意,峰顶一定存在故不用判断。
        int top = left;

        int index = findInMountainArrayleft(0, top, target, mountainArr);

        if (index == -1)
        {
            index = findInMountainArrayright(top, mountainArr.Length() - 1, target, mountainArr);
        }
        return(index);
    }
Ejemplo n.º 4
0
    private int findInMountainArrayright(int left, int right, int target, MountainArray mountainArr)
    {
        while (left < right)
        {
            int mid    = left + (right - left) / 2;
            int midNum = mountainArr.Get(mid);
            if (midNum > target)
            {
                left = mid + 1;
            }
            else if (midNum < target)
            {
                right = mid;
            }
            else if (midNum == target)
            {
                return(mid);
            }
        }

        // 区间缩小为一个元素时单独判断
        if (mountainArr.Get(left) == target)
        {
            return(left);
        }
        return(-1);
    }
Ejemplo n.º 5
0
    public int FindPeak(MountainArray arr)
    {
        int l = 0;
        int r = n - 1;

        while (l <= r)
        {
            int mid = l + (r - l) / 2;
            if (mid - 1 < 0 || arr.Get(mid) > arr.Get(mid - 1))
            {
                if (mid + 1 >= n || arr.Get(mid) > arr.Get(mid + 1))
                {
                    return(mid);
                }
                else
                {
                    l = mid + 1;
                }
            }
            else
            {
                r = mid - 1;
            }
        }
        return(-1);
    }
Ejemplo n.º 6
0
 private int BinarySearch(int target, MountainArray mountainArr, int left, int right, bool inc)
 {
     while (left <= right)
     {
         int mid = left + (right - left) / 2;
         var v   = mountainArr.Get(mid);
         if (v == target)
         {
             return(mid);
         }
         else if (v > target)
         {
             if (inc)
             {
                 right = mid - 1;
             }
             else
             {
                 left = mid + 1;
             }
         }
         else
         {
             if (inc)
             {
                 left = mid + 1;
             }
             else
             {
                 right = mid - 1;
             }
         }
     }
     return(-1);
 }
Ejemplo n.º 7
0
    public int FindInMountainArray(int target, MountainArray mountainArr)
    {
        int left  = 0;
        int right = mountainArr.Length() - 1;

        while (left < right)
        {
            int mid = left + (right - left) / 2;
            if (mountainArr.Get(mid) < mountainArr.Get(mid + 1))
            {
                left = mid + 1;
            }
            else
            {
                right = mid;
            }
        }
        int index = BinarySearch(target, mountainArr, 0, right, true);

        if (index == -1)
        {
            index = BinarySearch(target, mountainArr, left + 1, mountainArr.Length() - 1, false);
        }
        return(index);
    }
Ejemplo n.º 8
0
            public int FindInMountainArray(int target, MountainArray mountainArr)
            {
                int length = mountainArr.Length();
                int left   = 0;
                int right  = length - 1;

                while (left <= right)
                {
                    var mid = left + (right - left) / 2;
                    if (mountainArr.Get(mid) < mountainArr.Get(mid + 1))
                    {
                        left = mid + 1;
                    }
                    else
                    {
                        right = mid - 1;
                    }
                }
                var peak  = left;
                var index = BinarySearch(target, mountainArr, 0, peak, true);

                if (index < 0)
                {
                    index = BinarySearch(target, mountainArr, peak + 1, length - 1, false);
                }
                return(index);
            }
Ejemplo n.º 9
0
 public int BinarySearch(int target, MountainArray mountainArr, int left, int right, bool flag)
 {
     if (!flag)
     {
         target *= -1;
     }
     while (left <= right)
     {
         int mid     = left + (right - left) / 2;
         int mid_num = mountainArr.Get(mid);
         if (!flag)
         {
             mid_num *= -1;
         }
         if (mid_num == target)
         {
             return(mid);
         }
         else if (mid_num < target)
         {
             left = mid + 1;
         }
         else
         {
             right = mid - 1;
         }
     }
     return(-1);
 }
    public int FindDecreaseArray(int target, MountainArray mountainArr, int left, int right)
    {
        while (left < right)
        {
            var mid = (left + right) / 2;
            var val = mountainArr.Get(mid);

            if (val == target)
            {
                return(mid);
            }
            else if (val > target)
            {
                left = mid + 1;
            }
            else
            {
                right = mid;
            }
        }

        if (mountainArr.Get(left) == target)
        {
            return(left);
        }
        return(-1);
    }
Ejemplo n.º 11
0
    public int FindInMountainArray(int target, MountainArray A)
    {
        int n = A.Length(), l = 0, r = n - 1, m, peak = 0;

        // If I want find the index, I always use while (left < right)
        // If I may return the index during the search, I'll use while (left <= right)
        // find index of peak
        while (peak < r)
        {
            m = (peak + r) / 2;
            if (A.Get(m) < A.Get(m + 1))
            {
                peak = m + 1;
            }
            else
            {
                r = m;
            }
        }
        // find target in the left of peak
        int i = BinarySearch(A, target, 0, peak, true);

        // find target in the right of peak
        return(i != -1 ? i : BinarySearch(A, target, peak + 1, A.Length() - 1, false));
    }
    public int FindInMountainArray(int target, MountainArray mountainArr)
    {
        var left  = 0;
        var right = mountainArr.Length() - 1;
        var peak  = FindPeak(mountainArr, left, right);

        var findIncrease = FindIncreaseArray(target, mountainArr, left, peak);
        var findDecrease = FindDecreaseArray(target, mountainArr, peak, right);

        return(findIncrease != -1 ? findIncrease : findDecrease);
    }
Ejemplo n.º 13
0
            public int FindInMountainArray(int target, MountainArray mountainArr)
            {
                _len           = mountainArr.Length();
                _mountainArray = mountainArr;
                _peak          = FindPeak(1, _len - 1);
                if (GetHeight(_peak) == target)
                {
                    return(_peak);
                }
                var rs = FindBetween(target, 0, _peak - 1);

                return(rs != -1 ? rs : FindBetween(target, _peak + 1, _len - 1));
            }
 private int findMountainTop(MountainArray mountainArr, int left, int right)
 {
     while (left <= right)
     {
         int mid = left + (right - left) / 2;
         if (mountainArr.Get(mid) < mountainArr.Get(mid + 1))
         {
             left = mid + 1;
         }
         else
         {
             right = mid - 1;
         }
     }
     return(left);
 }
    /// <summary>
    /// 二分查找
    /// 1.先确定山顶
    /// 2.先从左侧找
    /// 3.如无再从右侧找
    /// 双百实现!!!
    /// </summary>
    /// <param name="target"></param>
    /// <param name="mountainArr"></param>
    /// <returns></returns>
    public int FindInMountainArray(int target, MountainArray mountainArr)
    {
        int len       = mountainArr.Length();
        int peakIndex = findMountainTop(mountainArr, 0, len - 1);

        if (mountainArr.Get(peakIndex) == target)
        {
            return(peakIndex);
        }
        int ret = findInSort(mountainArr, 0, peakIndex - 1, target);

        if (ret != -1)
        {
            return(ret);
        }
        return(findInReverse(mountainArr, peakIndex + 1, len - 1, target));
    }
Ejemplo n.º 16
0
    public int FindInMountainArray(int target, MountainArray mountainArr)
    {
        n    = mountainArr.Length();
        peak = FindPeak(mountainArr);
        if (mountainArr.Get(peak) == target)
        {
            return(peak);
        }

        int leftResult = SearchLeft(0, peak, target, mountainArr);

        if (leftResult != -1)
        {
            return(leftResult);
        }

        return(SearchRight(peak + 1, n - 1, target, mountainArr));
    }
Ejemplo n.º 17
0
        public void TestMethod10()
        {
            BinarySearch bs = new BinarySearch();

            //int[] A = new int[] { -10, -5, -2, 0, 4, 5, 6, 7, 8, 9, 10};
            //var index = bs.FixedPoint(A);

            //int[] nums = new int[] { 2, 4, 5, 5, 5, 5, 5, 6, 6 };
            //var ismajor = bs.IsMajorityElement(nums, 5);
            //string s = "abc";
            //string t = "ahbgdc";
            //var issub = bs.IsSubsequence(s, t);

            int[] nums = new int[] { 3, 5, 3, 2, 0 };
            var   ma   = new MountainArray(nums);

            var index = bs.FindInMountainArray(5, ma);
        }
    public int FindPeak(MountainArray mountainArr, int left, int right)
    {
        while (left < right)
        {
            var mid = (left + right) / 2;

            if (mountainArr.Get(mid) < mountainArr.Get(mid + 1))
            {
                left = mid + 1;
            }
            else
            {
                right = mid;
            }
        }

        return(left);
    }
Ejemplo n.º 19
0
 public int SearchRight(int l, int r, int t, MountainArray arr)
 {
     while (l <= r)
     {
         int mid = l + (r - l) / 2;
         if (arr.Get(mid) == t)
         {
             return(mid);
         }
         else if (arr.Get(mid) > t)
         {
             l = mid + 1;
         }
         else
         {
             r = mid - 1;
         }
     }
     return(-1);
 }
Ejemplo n.º 20
0
 int BinarySearch(MountainArray A, int target, int l, int r, bool asc)
 {
     while (l <= r)
     {
         int m   = (l + r) / 2;
         int val = A.Get(m);
         if (val == target)
         {
             return(m);
         }
         if (asc == val < target)
         {
             l = m + 1;
         }
         else
         {
             r = m - 1;
         }
     }
     return(-1);
 }
 private int findInSort(MountainArray mountainArr, int left, int right, int target)
 {
     while (left < right)
     {
         int mid = left + (right - left) / 2;
         int val = mountainArr.Get(mid);
         if (val == target)
         {
             return(mid);
         }
         if (val < target)
         {
             left = mid + 1;
         }
         else
         {
             right = mid - 1;
         }
     }
     return(mountainArr.Get(left) == target ? left : -1);
 }
Ejemplo n.º 22
0
    private int BinarySearchMountainArray(MountainArray mountainArr, int target, int start, int end, bool left = true)
    {
        while (start <= end)
        {
            // Use this approach instead of (start + end) / 2 to avoid overflow.
            int middle = start + (end - start) / 2;

            int currentValue = mountainArr.Get(middle);

            if (currentValue == target)
            {
                return(middle);
            }
            else if (currentValue > target)
            {
                if (left)
                {
                    end = middle - 1;
                }
                else
                {
                    start = middle + 1;
                }
            }
            else
            {
                if (left)
                {
                    start = middle + 1;
                }
                else
                {
                    end = middle - 1;
                }
            }
        }

        return(-1);
    }
Ejemplo n.º 23
0
        private static int FindInMountainArrayHelper(int target, MountainArray mountainArr, int a, int b, bool asc = true)
        {
            while (a <= b)
            {
                int curr = (a + b) / 2;
                int get  = mountainArr.Get(curr);
                if (get == target)
                {
                    return(curr);
                }

                if (get < target)
                {
                    if (asc)
                    {
                        a = curr + 1;
                    }
                    else
                    {
                        b = curr - 1;
                    }
                }
                else
                {
                    if (asc)
                    {
                        b = curr - 1;
                    }
                    else
                    {
                        a = curr + 1;
                    }
                }
            }

            return(-1);
        }
 public int FindInMountainArray(int target, MountainArray mountainArr)
 {
     throw new NotImplementedException();
 }
    public int FindInMountainArray(int target, MountainArray mountainArr)
    {
        int n = mountainArr.Length();
        int l = 0, r = n - 1, peak = 0;

        while (l < r)
        {
            int m = l + (r - l) / 2;

            if (mountainArr.Get(m) < mountainArr.Get(m + 1))
            {
                l    = m + 1;
                peak = m + 1;
            }
            else
            {
                r = m;
            }
        }

        l = 0;
        r = peak;

        while (l <= r)
        {
            int m = l + (r - l) / 2;

            int element = mountainArr.Get(m);
            if (element == target)
            {
                return(m);
            }
            else if (element < target)
            {
                l = m + 1;
            }
            else
            {
                r = m - 1;
            }
        }

        l = peak + 1;
        r = n - 1;

        while (l <= r)
        {
            int m = l + (r - l) / 2;

            int element = mountainArr.Get(m);
            if (element == target)
            {
                return(m);
            }
            else if (element > target)
            {
                l = m + 1;
            }
            else
            {
                r = m - 1;
            }
        }

        return(-1);
    }
    public int FindInMountainArray(int target, MountainArray mountainArr)
    {
        int left = 0, n = mountainArr.Length(), right = n - 1, peak;

        while (left < right)
        {
            int mid = left + (right - left) / 2, m = mountainArr.Get(mid), m1 = mountainArr.Get(mid + 1);
            if (m < m1)
            {
                left = mid + 1;
            }
            else
            {
                right = mid;
            }
        }
        if (mountainArr.Get(left) == target)
        {
            return(left);
        }
        peak  = left;
        left  = 0;
        right = peak;
        while (left < right)
        {
            int mid = left + (right - left) / 2, m = mountainArr.Get(mid);
            if (m == target)
            {
                return(mid);
            }
            else if (m < target)
            {
                left = mid + 1;
            }
            else
            {
                right = mid - 1;
            }
        }
        if (mountainArr.Get(left) == target)
        {
            return(left);
        }
        left  = peak + 1;
        right = n - 1;
        while (left < right)
        {
            int mid = left + (right - left) / 2, m = mountainArr.Get(mid);
            if (m == target)
            {
                return(mid);
            }
            else if (m > target)
            {
                left = mid + 1;
            }
            else
            {
                right = mid - 1;
            }
        }
        if (mountainArr.Get(right) == target)
        {
            return(right);
        }
        return(-1);
    }
Ejemplo n.º 27
0
 /** * // This is MountainArray's API interface. * // You should not implement it, or speculate about its implementation * class MountainArray { *     public int Get(int index) {} *     public int Length() {} * } */
 class Solution { public int FindInMountainArray(int target, MountainArray mountainArr)
                  {
                  }