<p>You are given a <strong>0-indexed</strong> integer array <code>nums</code>.</p>

<p>Initially, all of the indices are unmarked. You are allowed to make this operation any number of times:</p>

<ul>
	<li>Pick two <strong>different unmarked</strong> indices <code>i</code> and <code>j</code> such that <code>2 * nums[i] &lt;= nums[j]</code>, then mark <code>i</code> and <code>j</code>.</li>
</ul>

<p>Return <em>the maximum possible number of marked indices in <code>nums</code> using the above operation any number of times</em>.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> nums = [3,5,2,4]
<strong>Output:</strong> 2
<strong>Explanation: </strong>In the first operation: pick i = 2 and j = 1, the operation is allowed because 2 * nums[2] &lt;= nums[1]. Then mark index 2 and 1.
It can be shown that there&#39;s no other valid operation so the answer is 2.
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> nums = [9,2,5,4]
<strong>Output:</strong> 4
<strong>Explanation: </strong>In the first operation: pick i = 3 and j = 0, the operation is allowed because 2 * nums[3] &lt;= nums[0]. Then mark index 3 and 0.
In the second operation: pick i = 1 and j = 2, the operation is allowed because 2 * nums[1] &lt;= nums[2]. Then mark index 1 and 2.
Since there is no other operation, the answer is 4.
</pre>

<p><strong class="example">Example 3:</strong></p>

<pre>
<strong>Input:</strong> nums = [7,6,8]
<strong>Output:</strong> 0
<strong>Explanation: </strong>There is no valid operation to do, so the answer is 0.

</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= nums.length &lt;= 10<sup>5</sup></code></li>
	<li><code>1 &lt;= nums[i] &lt;= 10<sup>9</sup></code></li>
</ul>

<p>&nbsp;</p>
<style type="text/css">.spoilerbutton {display:block; border:dashed; padding: 0px 0px; margin:10px 0px; font-size:150%; font-weight: bold; color:#000000; background-color:cyan; outline:0; 
}
.spoiler {overflow:hidden;}
.spoiler > div {-webkit-transition: all 0s ease;-moz-transition: margin 0s ease;-o-transition: all 0s ease;transition: margin 0s ease;}
.spoilerbutton[value="Show Message"] + .spoiler > div {margin-top:-500%;}
.spoilerbutton[value="Hide Message"] + .spoiler {padding:5px;}
</style>

'''
通过二分查找的方式，找到数组 nums 中可以标记的最大数量的索引对，
使得每一对中的两个元素满足特定的条件。
最终返回的是这些索引对的数量乘以 2，因为每一对包含两个索引
'''
class Solution:
    def maxNumOfMarkedIndices(self, nums: List[int]) -> int:
        # 对数组 nums 进行排序。排序后，数组中的元素按从小到大的顺序排列
        nums.sort()
        # left 和 right 是二分查找的左右边界。
        # 初始时，left 设为 0，right 设为数组长度的一半加一。
        # 这里的 right 是一个开区间，表示查找的范围是 [left, right)
        left, right = 0, len(nums) // 2 + 1  # 开区间

        # 这是一个二分查找的循环条件。
        # 循环会持续进行，直到 left 和 right 之间的距离小于 2
        while left + 1 < right:
            # k 是当前二分查找的中间点。k 的值是 left 和 right 的中间值
            k = (left + right) // 2

            # 这个条件检查是否存在 k 对满足条件的索引对。
            # 具体来说，它检查数组中前 k 个元素是否都能找到一个在其之前的元素，
            # 使得该元素的值至少是前者的两倍
            if all(nums[i] * 2 <= nums[i - k] for i in range(k)):
                # 如果条件满足，说明当前的 k 对是有效的，
                # 因此将 left 更新为 k，继续查找更大的 k
                left = k
            else:
                # 如果条件不满足，说明当前的 k 对无效，因此将 right 更新为 k，缩小查找范围
                right = k
        return left * 2  # 最多匹配 left 对，有 left * 2 个数
654