// 方法一:交换。比较符合直觉的O1思路。不过需要遍历的轮数gcd(k,n)是推导的结果 classSolution { public: voidrotate(vector<int>& nums, int k){ int n = nums.size(); k = k % n; int count = gcd(k, n); for (int start = 0; start < count; ++start) { int current = start; int prev = nums[start]; do { int next = (current + k) % n; swap(nums[next], prev); current = next; } while (start != current); } } }; // 方法2: 巧妙的思路,最后的k%n个元素会变到开头 // 联想到翻转操作的数组原语 // 我们只需要先翻转整个数组,再分别翻转前k%n个和其余的,翻转三次即可 classSolution { public: voidreverse(vector<int>& nums, int start, int end){ while (start < end) { swap(nums[start], nums[end]); start += 1; end -= 1; } }
voidrotate(vector<int>& nums, int k){ k %= nums.size(); reverse(nums, 0, nums.size() - 1); reverse(nums, 0, k - 1); reverse(nums, k, nums.size() - 1); } };
int l = 0, r = -1; int len = INT_MAX, ansL = -1, ansR = -1;
while (r < int(s.size())) { if (ori.find(s[++r]) != ori.end()) { ++cnt[s[r]]; } while (check() && l <= r) { if (r - l + 1 < len) { len = r - l + 1; ansL = l; } if (ori.find(s[l]) != ori.end()) { --cnt[s[l]]; } ++l; } }