{"id":8367,"date":"2021-04-18T09:18:06","date_gmt":"2021-04-18T16:18:06","guid":{"rendered":"https:\/\/zxi.mytechroad.com\/blog\/?p=8367"},"modified":"2021-04-18T09:18:23","modified_gmt":"2021-04-18T16:18:23","slug":"leetcode-1830-minimum-number-of-operations-to-make-string-sorted","status":"publish","type":"post","link":"https:\/\/zxi.mytechroad.com\/blog\/math\/leetcode-1830-minimum-number-of-operations-to-make-string-sorted\/","title":{"rendered":"\u82b1\u82b1\u9171 LeetCode 1830. Minimum Number of Operations to Make String Sorted"},"content":{"rendered":"\n<p>You are given a string&nbsp;<code>s<\/code>&nbsp;(<strong>0-indexed<\/strong>)\u200b\u200b\u200b\u200b\u200b\u200b. You are asked to perform the following operation on&nbsp;<code>s<\/code>\u200b\u200b\u200b\u200b\u200b\u200b until you get a sorted string:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Find&nbsp;<strong>the largest index<\/strong>&nbsp;<code>i<\/code>&nbsp;such that&nbsp;<code>1 &lt;= i &lt; s.length<\/code>&nbsp;and&nbsp;<code>s[i] &lt; s[i - 1]<\/code>.<\/li><li>Find&nbsp;<strong>the largest index<\/strong>&nbsp;<code>j<\/code>&nbsp;such that&nbsp;<code>i &lt;= j &lt; s.length<\/code>&nbsp;and&nbsp;<code>s[k] &lt; s[i - 1]<\/code>&nbsp;for all the possible values of&nbsp;<code>k<\/code>&nbsp;in the range&nbsp;<code>[i, j]<\/code>&nbsp;inclusive.<\/li><li>Swap the two characters at indices&nbsp;<code>i - 1<\/code>\u200b\u200b\u200b\u200b and&nbsp;<code>j<\/code>\u200b\u200b\u200b\u200b\u200b.<\/li><li>Reverse the suffix starting at index&nbsp;<code>i<\/code>\u200b\u200b\u200b\u200b\u200b\u200b.<\/li><\/ol>\n\n\n\n<p>Return&nbsp;<em>the number of operations needed to make the string sorted.<\/em>&nbsp;Since the answer can be too large, return it&nbsp;<strong>modulo<\/strong>&nbsp;<code>10<sup>9<\/sup>&nbsp;+ 7<\/code>.<\/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> s = \"cba\"\n<strong>Output:<\/strong> 5\n<strong>Explanation:<\/strong> The simulation goes as follows:\nOperation 1: i=2, j=2. Swap s[1] and s[2] to get s=\"cab\", then reverse the suffix starting at 2. Now, s=\"cab\".\nOperation 2: i=1, j=2. Swap s[0] and s[2] to get s=\"bac\", then reverse the suffix starting at 1. Now, s=\"bca\".\nOperation 3: i=2, j=2. Swap s[1] and s[2] to get s=\"bac\", then reverse the suffix starting at 2. Now, s=\"bac\".\nOperation 4: i=1, j=1. Swap s[0] and s[1] to get s=\"abc\", then reverse the suffix starting at 1. Now, s=\"acb\".\nOperation 5: i=2, j=2. Swap s[1] and s[2] to get s=\"abc\", then reverse the suffix starting at 2. Now, s=\"abc\".\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> s = \"aabaa\"\n<strong>Output:<\/strong> 2\n<strong>Explanation:<\/strong> The simulation goes as follows:\nOperation 1: i=3, j=4. Swap s[2] and s[4] to get s=\"aaaab\", then reverse the substring starting at 3. Now, s=\"aaaba\".\nOperation 2: i=4, j=4. Swap s[3] and s[4] to get s=\"aaaab\", then reverse the substring starting at 4. Now, s=\"aaaab\".\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> s = \"cdbea\"\n<strong>Output:<\/strong> 63<\/pre>\n\n\n\n<p><strong>Example 4:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted;crayon:false\"><strong>Input:<\/strong> s = \"leetcodeleetcodeleetcode\"\n<strong>Output:<\/strong> 982157772\n<\/pre>\n\n\n\n<p><strong>Constraints:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><code>1 &lt;= s.length &lt;= 3000<\/code><\/li><li><code>s<\/code>\u200b\u200b\u200b\u200b\u200b\u200b consists only of lowercase English letters.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Solution: Math<\/strong><\/h2>\n\n\n\n<p>Time complexity: O(26n)<br>Space complexity: O(n)<\/p>\n\n\n\n<div class=\"responsive-tabs\">\n<h2 class=\"tabtitle\">C++<\/h2>\n<div class=\"tabcontent\">\n\n<pre lang=\"c++\">\nconstexpr int kMod = 1e9 + 7;\nint64_t powm(int64_t b, int64_t p) {\n  int64_t ans = 1;\n  while (p) {\n    if (p & 1) ans = (ans * b) % kMod;\n    b = (b * b) % kMod;\n    p >>= 1;\n  }\n  return ans;\n}\n\nclass Solution {\npublic:\n  int makeStringSorted(string s) {\n    const int n = s.length();    \n    vector<int64_t> fact(n + 1, 1);\n    vector<int64_t> inv(n + 1, 1);    \n    \n    for (int i = 1; i <= n; ++i) {\n      fact[i] = (fact[i - 1] * i) % kMod;\n      inv[i] = powm(fact[i], kMod - 2);\n    }\n    \n    int64_t ans = 0;\n    vector<int> freq(26);\n    for (int i = n - 1; i >= 0; --i) {\n      const int idx = s[i] - 'a';\n      ++freq[idx];\n      int64_t cur = accumulate(begin(freq), begin(freq) + idx, 0ll) *\n                      fact[n - i - 1] % kMod;\n      for (int f : freq)\n        cur = cur * inv[f] % kMod;      \n      ans = (ans + cur) % kMod;\n    }\n    return ans;\n  }\n};\n<\/pre>\n<\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>You are given a string&nbsp;s&nbsp;(0-indexed)\u200b\u200b\u200b\u200b\u200b\u200b. You are asked to perform the following operation on&nbsp;s\u200b\u200b\u200b\u200b\u200b\u200b until you get a sorted string: Find&nbsp;the largest index&nbsp;i&nbsp;such that&nbsp;1 &lt;=&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[49],"tags":[217,31,121,4],"class_list":["post-8367","post","type-post","status-publish","format-standard","hentry","category-math","tag-hard","tag-math","tag-permutation","tag-string","entry","simple"],"_links":{"self":[{"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/posts\/8367","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=8367"}],"version-history":[{"count":2,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/posts\/8367\/revisions"}],"predecessor-version":[{"id":8369,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/posts\/8367\/revisions\/8369"}],"wp:attachment":[{"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/media?parent=8367"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/categories?post=8367"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/tags?post=8367"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}