<p>You are given an integer array <code>nums</code> and an integer <code>x</code>. In one operation, you can either remove the leftmost or the rightmost element from the array <code>nums</code> and subtract its value from <code>x</code>. Note that this <strong>modifies</strong> the array for future operations.</p>

<p>Return <em>the <strong>minimum number</strong> of operations to reduce </em><code>x</code> <em>to <strong>exactly</strong></em> <code>0</code> <em>if it is possible</em><em>, otherwise, return </em><code>-1</code>.</p>

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

<pre>
<strong>Input:</strong> nums = [1,1,4,2,3], x = 5
<strong>Output:</strong> 2
<strong>Explanation:</strong> The optimal solution is to remove the last two elements to reduce x to zero.
</pre>

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

<pre>
<strong>Input:</strong> nums = [5,6,7,8,9], x = 4
<strong>Output:</strong> -1
</pre>

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

<pre>
<strong>Input:</strong> nums = [3,2,20,1,1,3], x = 10
<strong>Output:</strong> 5
<strong>Explanation:</strong> The optimal solution is to remove the last three elements and the first two elements (5 operations in total) to reduce x to zero.
</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>4</sup></code></li>
	<li><code>1 &lt;= x &lt;= 10<sup>9</sup></code></li>
</ul>

class Solution:
  l_pref_sum = []
  r_pref_sum = []
  def minOperations(self, nums: List[int], x: int) -> int:
    self.l_pref_sum=[]
    self.r_pref_sum=[]
    l=0
    r=len(nums)-1
    l_total=0
    r_total=0
    while l<len(nums):
      l_total+=nums[l]
      self.l_pref_sum.append(l_total)
      l+=1
      r_total += nums[r]
      self.r_pref_sum.append(r_total)
      r-=1


    def binarySearch(l,h,target,arr):
      while l<=h:
        mid=(l+h)//2
        if arr[mid]==target:
          return mid
        elif arr[mid]<target:
          l=mid+1
        elif arr[mid]>target:
          h=mid-1
      return -1


    i=-1
    min_moves=math.inf
    flag=False
    while i<len(self.l_pref_sum):
      left_sum=0
      moves=0
      if i>=0:
        left_sum=self.l_pref_sum[i]
      if left_sum==x:
        moves=i+1
        if moves<min_moves:
          min_moves=moves
          flag=True
      elif left_sum<x:
        moves = i + 1
        rem=x-left_sum
        rem_i=(len(self.l_pref_sum)-1)-i
        r_i=binarySearch(0,rem_i-1,rem,self.r_pref_sum)
        if r_i>=0:
          moves+=(r_i+1)
          if moves<min_moves:
            min_moves=moves
            flag = True
      else:
        break
      i+=1

    i = -1
    while i < len(self.r_pref_sum):
      right_sum = 0
      if i >= 0:
        right_sum = self.r_pref_sum[i]
      if right_sum == x:
        moves = i + 1
        if moves < min_moves:
          min_moves = moves
          flag = True
      elif right_sum < x:
        moves = i + 1
        rem = x - right_sum
        rem_i = (len(self.r_pref_sum) - 1) - i
        l_i = binarySearch(0, rem_i - 1, rem, self.l_pref_sum)
        if l_i >= 0:
          moves += (l_i + 1)
          if moves < min_moves:
            min_moves = moves
            flag = True
      else:
        break
      i += 1
    if flag==True:
      return min_moves
    return -1
30400