題目連結:
題目意譯:
給定一個按非遞減順序排序的陣列 nums,回傳正整數數量與負整數數量兩數的最大值。
換句話說,如果 nums 中正整數的數量為 pos 而負整數的數量為 neg,則回傳 pos 和 neg 中的最大值。
注意到 0 不正也不負。
限制:
1 ≦ nums.length ≦ 2000
-2000 ≦ nums[i] ≦ 2000
nums 是以非遞減順序排序的。
進階:你可以在時間複雜度為 O(lon(n)) 的情況下解出本題嗎?
範例測資:
範例 1:
輸入: nums = [-2,-1,-1,1,2,3]
輸出: 3
解釋: There are 3 positive integers and 3 negative integers. The maximum count among them is 3.
範例 2:
輸入: nums = [-3,-2,-1,0,0,1,2]
輸出: 3
解釋: There are 2 positive integers and 3 negative integers. The maximum count among them is 3.
範例 3:
輸入: nums = [5,20,66,1314]
輸出: 4
解釋: There are 4 positive integers and 0 negative integers. The maximum count among them is 4.
解題思維:
線性解很簡單,就是單純地掃過並統計正數和負數各自的數量,最後再比較即可。
而 O(log(n)) 的解則需要利用 nums 是以非遞減順序排序的這個性質——也就是用兩次二分搜來找到「最小的正整數」以及「最大的負整數」各自的位置,稱其為 x 和 y。前者可以視為第一個大於 0 的數字、後者為第一個大於等於 0 的數字之前一個數字,所以可以分別用 upper_bound() 和 lower_bound() 來找(這是以 C++ 為準;若是 Python 則是 bisect_left() 和 bisect_right())。
如果找不到最小的正整數,則回傳 y + 1(沒有負整數的話,則此視為 0。後面也是同理);
如果連 0 都找不到,代表整個陣列都是負數,因此回傳 nums.length 即可;
剩下的直接回傳 max(nums.length - x, y + 1) 即可。
此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。