31. 下一个排列
实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须 原地 修改,只允许使用额外常数空间。
示例 1:
输入:nums = [1,2,3]
输出:[1,3,2]
示例 2:
输入:nums = [3,2,1]
输出:[1,2,3]
示例 3:
输入:nums = [1,1,5]
输出:[1,5,1]
示例 4:
输入:nums = [1]
输出:[1]
提示:
1 <= nums.length <= 100
0 <= nums[i] <= 100
fun _0031_nextPermutation() {
println("--------_0031_nextPermutation-------")
nextPermutation(intArrayOf(1, 2, 3))
nextPermutation(intArrayOf(3, 2, 1))
nextPermutation(intArrayOf(1, 1, 5))
nextPermutation(intArrayOf(1))
}
fun nextPermutation(nums: IntArray) {
val n = nums.size;
var i = n - 2;
var j = n - 1
while (i >= 0 && nums[i] >= nums[i + 1]) --i
if (i >= 0) {
while (nums[j] <= nums[i]) --j
swap(i, j, nums)
}
reverse(nums, i + 1)
println(nums.contentToString())
}
private fun reverse(nums: IntArray, index: Int) {
var i = index
var j = nums.size - 1
while (i < j) {
swap(i, j, nums)
i++
j--
}
}
private fun swap(i: Int, j: Int, nums: IntArray) {
val temp = nums[i]
nums[i] = nums[j]
nums[j] = temp
}
32. 最长有效括号
给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。
示例 1:
输入: "(()"
输出: 2
解释: 最长有效括号子串为 "()"
示例 2:
输入: ")()())"
输出: 4
解释: 最长有效括号子串为 "()()"
fun _0032_longestValidParentheses() {
println("--------_0032_longestValidParentheses-------")
println(longestValidParentheses("(()"))
println(longestValidParentheses(")()())"))
println(longestValidParentheses("(()()())"))
println(longestValidParentheses("()()())"))
println(longestValidParentheses("(()()()"))
}
fun longestValidParentheses(s: String): Int {
var res = 0;
var start = 0;
val st = Stack<Int>()
for (i in s.indices) {
if (s[i] == '(') {
st.push(i)
} else if (s[i] == ')') {
if (st.empty()) {
start = i + 1
} else {
st.pop()
res = if (st.empty()) Math.max(res, i - start + 1) else Math.max(res, i - st.peek())
}
}
}
return res
}
33. 搜索旋转排序数组
给你一个整数数组 nums ,和一个整数 target 。
该整数数组原本是按升序排列,但输入时在预先未知的某个点上进行了旋转。(例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
请你在数组中搜索 target ,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。
示例 1:
输入:nums = [4,5,6,7,0,1,2], target = 0
输出:4
示例 2:
输入:nums = [4,5,6,7,0,1,2], target = 3
输出:-1
示例 3:
输入:nums = [1], target = 0
输出:-1
提示:
1 <= nums.length <= 5000
-10^4 <= nums[i] <= 10^4
nums 中的每个值都 独一无二
nums 肯定会在某个点上旋转
-10^4 <= target <= 10^4
fun _0033_search() {
println("--------_0033_search-------")
println(search(intArrayOf(4, 5, 6, 7, 0, 1, 2), 0))
println(search(intArrayOf(4, 5, 6, 7, 0, 1, 2), 3))
println(search(intArrayOf(1), 0))
println(search(intArrayOf(3, 1), 1))
println(search(intArrayOf(3, 1), 3))
}
fun search(nums: IntArray, target: Int): Int {
var left = 0
var right = nums.size - 1
while (left <= right) {
val mid = left + (right - left) / 2
if (nums[mid] == target)
return mid
if (nums[mid] < nums[right]) {
if (nums[mid] < target && nums[right] >= target)
left = mid + 1
else
right = mid - 1
} else {
if (nums[left] <= target && nums[mid] > target)
right = mid - 1
else
left = mid + 1
}
}
return -1
}
34. 在排序数组中查找元素的第一个和最后一个位置
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
你的算法时间复杂度必须是 O(log n) 级别。
如果数组中不存在目标值,返回 [-1, -1]。
示例 1:
输入: nums = [5,7,7,8,8,10], target = 8
输出: [3,4]
示例 2:
输入: nums = [5,7,7,8,8,10], target = 6
输出: [-1,-1]
fun _0034_searchRange() {
println("--------_0034_searchRange-------")
println(searchRange(intArrayOf(5, 7, 7, 8, 8, 10), 10).contentToString())
println(searchRange(intArrayOf(5, 7, 7, 8, 8, 10), 9).contentToString())
println(searchRange(intArrayOf(5, 7, 7, 8, 8, 10), 8).contentToString())
println(searchRange(intArrayOf(5, 7, 7, 8, 8, 10), 7).contentToString())
println(searchRange(intArrayOf(5, 7, 7, 8, 8, 10), 6).contentToString())
println(searchRange(intArrayOf(5, 7, 7, 8, 8, 10), 5).contentToString())
}
fun searchRange(nums: IntArray, target: Int): IntArray {
val res = intArrayOf(-1, -1)
var left = 0
var right = nums.size
while (left < right) {
val mid = left + (right - left) / 2
if (nums[mid] < target)
left = mid + 1
else
right = mid
}
if (right == nums.size || nums[right] != target)
return res
res[0] = right
right = nums.size
while (left < right) {
val mid = left + (right - left) / 2
if (nums[mid] <= target)
left = mid + 1
else
right = mid
}
res[1] = right - 1
return res
}
35. 搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
示例 1:
输入: [1,3,5,6], 5
输出: 2
示例 2:
输入: [1,3,5,6], 2
输出: 1
示例 3:
输入: [1,3,5,6], 7
输出: 4
示例 4:
输入: [1,3,5,6], 0
输出: 0
fun _0035_searchInsert() {
println("--------_0035_searchInsert-------")
println(searchInsert(intArrayOf(1, 3, 5, 6), 5))
println(searchInsert(intArrayOf(1, 3, 5, 6), 2))
println(searchInsert(intArrayOf(1, 3, 5, 6), 7))
println(searchInsert(intArrayOf(1, 3, 5, 6), 0))
}
fun searchInsert(nums: IntArray, target: Int): Int {
if (nums.last() < target) return nums.size
var left = 0
var right = nums.size
while (left < right) {
val mid = left + (right - left) / 2
if (nums[mid] < target)
left = mid + 1
else
right = mid
}
return right
}
我是今阳,如果想要进阶和了解更多的干货,欢迎关注公众号”今阳说“接收我的最新文章