diff --git a/leetcode/0031.Next-Permutation/31. Next Permutation.go b/leetcode/0031.Next-Permutation/31. Next Permutation.go index 94493516..caf2a43e 100644 --- a/leetcode/0031.Next-Permutation/31. Next Permutation.go +++ b/leetcode/0031.Next-Permutation/31. Next Permutation.go @@ -1,31 +1,55 @@ +// https://leetcode.com/problems/next-permutation/discuss/1554932/Go-Submission-with-Explanation +// Time O(N) , Space: O(1) + package leetcode +// [2,(3),6,5,4,1] -> 2,(4),6,5,(3),1 -> 2,4, 1,3,5,6 func nextPermutation(nums []int) { - i, j := 0, 0 - for i = len(nums) - 2; i >= 0; i-- { - if nums[i] < nums[i+1] { + var n = len(nums) + var pIdx = checkPermutationPossibility(nums) + if pIdx == -1 { + reverse(nums, 0, n-1) + return + } + + var rp = len(nums) - 1 + // start from right most to leftward,find the first number which is larger than PIVOT + for rp > 0 { + if nums[rp] > nums[pIdx] { + swap(nums, pIdx, rp) break + } else { + rp-- } } - if i >= 0 { - for j = len(nums) - 1; j > i; j-- { - if nums[j] > nums[i] { - break - } - } - swap(&nums, i, j) - } - reverse(&nums, i+1, len(nums)-1) + // Finally, Reverse all elements which are right from pivot + reverse(nums, pIdx+1, n-1) } -func reverse(nums *[]int, i, j int) { - for i < j { - swap(nums, i, j) - i++ - j-- +func swap(nums []int, i, j int) { + nums[i], nums[j] = nums[j], nums[i] +} + +func reverse(nums []int, s int, e int) { + for s < e { + swap(nums, s, e) + s++ + e-- } } -func swap(nums *[]int, i, j int) { - (*nums)[i], (*nums)[j] = (*nums)[j], (*nums)[i] +// checkPermutationPossibility returns 1st occurrence Index where +// value is in decreasing order(from right to left) +// returns -1 if not found(it's already in its last permutation) +func checkPermutationPossibility(nums []int) (idx int) { + // search right to left for 1st number(from right) that is not in increasing order + var rp = len(nums) - 1 + for rp > 0 { + if nums[rp-1] < nums[rp] { + idx = rp - 1 + return idx + } + rp-- + } + return -1 } diff --git a/leetcode/0048.Rotate-Image/48. Rotate Image.go b/leetcode/0048.Rotate-Image/48. Rotate Image.go index 9b37fa61..a0fdf951 100644 --- a/leetcode/0048.Rotate-Image/48. Rotate Image.go +++ b/leetcode/0048.Rotate-Image/48. Rotate Image.go @@ -1,17 +1,45 @@ +// Time: O(N) Space: O(1) + package leetcode func rotate(matrix [][]int) { - length := len(matrix) - // rotate by diagonal 对角线变换 - for i := 0; i < length; i++ { - for j := i + 1; j < length; j++ { - matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j] - } + n := len(matrix) + if n == 1 { + return } - // rotate by vertical centerline 竖直轴对称翻转 - for i := 0; i < length; i++ { - for j := 0; j < length/2; j++ { - matrix[i][j], matrix[i][length-j-1] = matrix[i][length-j-1], matrix[i][j] + /* rotate clock-wise = 1. transpose matrix => 2. reverse(matrix[i]) + + 1 2 3 4 1 5 9 13 13 9 5 1 + 5 6 7 8 => 2 6 10 14 => 14 10 6 2 + 9 10 11 12 3 7 11 15 15 11 7 3 + 13 14 15 16 4 8 12 16 16 12 8 4 + + */ + + for i := 0; i < n; i++ { + // transpose, i=rows, j=columns + // j = i+1, coz diagonal elements didn't change in a square matrix + for j := i + 1; j < n; j++ { + swap(matrix, i, j) } + // reverse each row of the image + matrix[i] = reverse(matrix[i]) } } + +// swap changes original slice's i,j position +func swap(nums [][]int, i, j int) { + nums[i][j], nums[j][i] = nums[j][i], nums[i][j] +} + +// reverses a row of image, matrix[i] +func reverse(nums []int) []int { + var lp, rp = 0, len(nums) - 1 + + for lp < rp { + nums[lp], nums[rp] = nums[rp], nums[lp] + lp++ + rp-- + } + return nums +}