{"id":7853,"date":"2020-12-26T23:56:26","date_gmt":"2020-12-27T07:56:26","guid":{"rendered":"https:\/\/zxi.mytechroad.com\/blog\/?p=7853"},"modified":"2020-12-27T00:10:21","modified_gmt":"2020-12-27T08:10:21","slug":"leetcode-1703-minimum-adjacent-swaps-for-k-consecutive-ones","status":"publish","type":"post","link":"https:\/\/zxi.mytechroad.com\/blog\/sliding-window\/leetcode-1703-minimum-adjacent-swaps-for-k-consecutive-ones\/","title":{"rendered":"\u82b1\u82b1\u9171 LeetCode 1703. Minimum Adjacent Swaps for K Consecutive Ones"},"content":{"rendered":"\n<p>You are given an integer array,&nbsp;<code>nums<\/code>, and an integer&nbsp;<code>k<\/code>.&nbsp;<code>nums<\/code>&nbsp;comprises of only&nbsp;<code>0<\/code>&#8216;s and&nbsp;<code>1<\/code>&#8216;s. In one move, you can choose two&nbsp;<strong>adjacent<\/strong>&nbsp;indices and swap their values.<\/p>\n\n\n\n<p>Return&nbsp;<em>the&nbsp;<strong>minimum<\/strong>&nbsp;number of moves required so that&nbsp;<\/em><code>nums<\/code><em>&nbsp;has&nbsp;<\/em><code>k<\/code><em>&nbsp;<strong>consecutive<\/strong>&nbsp;<\/em><code>1<\/code><em>&#8216;s<\/em>.<\/p>\n\n\n\n<p><strong>Example 1:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted;crayon:false\"><strong>Input:<\/strong> nums = [1,0,0,1,0,1], k = 2\n<strong>Output:<\/strong> 1\n<strong>Explanation:<\/strong> In 1 move, nums could be [1,0,0,0,1,1] and have 2 consecutive 1's.\n<\/pre>\n\n\n\n<p><strong>Example 2:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted;crayon:false\"><strong>Input:<\/strong> nums = [1,0,0,0,0,0,1,1], k = 3\n<strong>Output:<\/strong> 5\n<strong>Explanation:<\/strong> In 5 moves, the leftmost 1 can be shifted right until nums = [0,0,0,0,0,1,1,1].\n<\/pre>\n\n\n\n<p><strong>Example 3:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted;crayon:false\"><strong>Input:<\/strong> nums = [1,1,0,1], k = 2\n<strong>Output:<\/strong> 0\n<strong>Explanation:<\/strong> nums already has 2 consecutive 1's.\n<\/pre>\n\n\n\n<p><strong>Constraints:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><code>1 &lt;= nums.length &lt;= 10<sup>5<\/sup><\/code><\/li><li><code>nums[i]<\/code>&nbsp;is&nbsp;<code>0<\/code>&nbsp;or&nbsp;<code>1<\/code>.<\/li><li><code>1 &lt;= k &lt;= sum(nums)<\/code><\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Solution: Prefix Sum + Sliding Window<\/strong><\/h2>\n\n\n\n<p>Time complexity: O(n)<br>Space complexity: O(n)<\/p>\n\n\n\n<p>We only care positions of 1s, we can move one element from position x to y (assuming x + 1 ~ y are all zeros) in y &#8211; x steps. e.g. [0 0 1 0 0 0 1] =&gt; [0 0 0 0 0 1 1], move first 1 at position 2 to position 5, cost is 5 &#8211; 2 = 3.<\/p>\n\n\n\n<p>Given a size k window of indices of ones, the optimal solution it to use the median number as center. We can compute the cost to form consecutive numbers:<\/p>\n\n\n\n<p>e.g. [1 4 7 9 10] =&gt; [5 6 7 8 9] cost = (5 &#8211; 1) + (6 &#8211; 4) + (9 &#8211; 8) + (10 &#8211; 9) = 8<\/p>\n\n\n\n<p>However, naive solution takes O(n*k) =&gt; TLE.<\/p>\n\n\n\n<p>We can use prefix sum to compute the cost of a window in O(1) to reduce time complexity to O(n)<\/p>\n\n\n\n<p>First, in order to use sliding window, we change the target of every number in the window to the median number.<br>e.g. [1 4 7 9 10] =&gt; [7 7 7 7 7] cost = (7 &#8211; 1) + (7 &#8211; 4) + (7 &#8211; 7) + (9 &#8211; 7) + (10 &#8211; 7) = (9 + 10) &#8211; (1 + 4) = right &#8211; left. <br>[5 6 7 8 9] =&gt; [7 7 7 7 7] takes extra 2 + 1 + 1 + 2 = 6 steps =  (k \/ 2) * ((k + 1) \/ 2), these extra steps should be deducted from the final answer. <\/p>\n\n\n\n<div class=\"responsive-tabs\">\n<h2 class=\"tabtitle\">C++<\/h2>\n<div class=\"tabcontent\">\n\n<pre lang=\"c++\">\nclass Solution {\npublic:\n  int minMoves(vector<int>& nums, int k) {\n    vector<long> s(1);\n    for (int i = 0; i < nums.size(); ++i)\n      if (nums[i])\n        s.push_back(s.back() + i);\n    const int n = s.size();\n    long ans = 1e10;\n    const int m1 = k \/ 2, m2 = (k + 1) \/ 2;\n    for (int i = 0; i + k < n; ++i) {\n      const long right = s[i + k] - s[i + m1];\n      const long left = s[i + m2] - s[i];\n      ans = min(ans, right - left);\n    }\n    return ans - m1 * m2;\n  }\n};\n<\/pre>\n\n<\/div><h2 class=\"tabtitle\">Python3<\/h2>\n<div class=\"tabcontent\">\n\n<pre lang=\"python\">\nclass Solution:\n  def minMoves(self, nums: List[int], k: int) -> int:\n    ans = 1e10\n    s = [0]    \n    for i, v in enumerate(nums):\n      if v: s.append(s[-1] + i)\n    n = len(s)\n    m1 = k \/\/ 2\n    m2 = (k + 1) \/\/ 2\n    for i in range(n - k):\n      right = s[i + k] - s[i + m1]\n      left = s[i + m2] - s[i]\n      ans = min(ans, right - left)\n    return ans - m1 * m2\n<\/pre>\n<\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>You are given an integer array,&nbsp;nums, and an integer&nbsp;k.&nbsp;nums&nbsp;comprises of only&nbsp;0&#8216;s and&nbsp;1&#8216;s. In one move, you can choose two&nbsp;adjacent&nbsp;indices and swap their values. Return&nbsp;the&nbsp;minimum&nbsp;number of&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[476],"tags":[679,217,200,215],"class_list":["post-7853","post","type-post","status-publish","format-standard","hentry","category-sliding-window","tag-consecutive","tag-hard","tag-prefix-sum","tag-sliding-window","entry","simple"],"_links":{"self":[{"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/posts\/7853","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/comments?post=7853"}],"version-history":[{"count":2,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/posts\/7853\/revisions"}],"predecessor-version":[{"id":7855,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/posts\/7853\/revisions\/7855"}],"wp:attachment":[{"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/media?parent=7853"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/categories?post=7853"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/tags?post=7853"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}