递增的三元子序列
给你一个整数数组 nums ,判断这个数组中是否存在长度为 3 的递增子序列。
如果存在这样的三元组下标 (i, j, k) 且满足 i < j < k ,使得 nums[i] < nums[j] < nums[k] ,返回 true ;否则,返回 false 。
示例 1:
输入:nums = [1,2,3,4,5]
输出:true
解释:任何 i < j < k 的三元组都满足题意
示例 2:
输入:nums = [5,4,3,2,1]
输出:false
解释:不存在满足题意的三元组
示例 3:
输入:nums = [2,1,5,0,4,6]
输出:true
解释:三元组 (3, 4, 5) 满足题意,因为 nums[3] == 0 < nums[4] == 4 < nums[5] == 6
提示:
1 <= nums.length <= 105
-231 <= nums[i] <= 231 - 1
进阶:你能实现时间复杂度为 O(n) ,空间复杂度为 O(1) 的解决方案吗?
解题思路一
1.找到最小值和次小的值,通过跟当前元素进行比较;
2.更新最小值和次小值
2.否则即满足条件
//引入math库
import (
"math"
)
func increasingTriplet(nums []int) bool {
//记录最小值和第二小的值
m1, m2 := math.MaxInt32, math.MaxInt32
for _, v := range nums {
//找到子序列第一个元素,不断更新
if m1 >= v {
m1 = v
} else if m2 >= v {
//找到子序列第二个元素,不断更新
m2 = v
} else {
//找到第三个,满足要求
return true
}
}
return false
}
Javascript
/**
* @param {number[]} nums
* @return {boolean}
*/
var increasingTriplet = function (nums) {
let min = nums[0], temp = Number.MAX_VALUE
// 最小值,中间值
for (let i = 1; i < nums.length-1; i++) {
//找到最小值
min = Math.min(min, nums[i])
//找到中间值
if (nums[i] > min) {
temp = nums[i]
}
//找到第三个值
if (temp < nums[i + 1]) {
return true
}
}
return false
};
编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:
每行中的整数从左到右按升序排列。
每行的第一个整数大于前一行的最后一个整数。
示例 1:
输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
输出:true
示例 2:
输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13
输出:false
提示:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 100
-104 <= matrix[i][j], target <= 104
Go 数组查找
func searchMatrix(matrix [][]int, target int) bool {
m := len(matrix)
n := len(matrix[0])
var i = 0
for i < m && n > 0 {
if target == matrix[i][n-1] {
return true
} else if target < matrix[i][n-1] {
n--
} else {
i++
}
}
return false
}
javascript 暴力解法
/**
* @param {number[][]} matrix
* @param {number} target
* @return {boolean}
*/
var searchMatrix = function(matrix, target) {
for(let i=0;i<matrix.length;i++){
for(let j=0;j<matrix[0].length;j++){
if(matrix[i][j]===target){
return true
}
}
}
return false
};
javascript 数组查找
/**
* @param {number[][]} matrix
* @param {number} target
* @return {boolean}
*/
/*
以二维数组左下角为原点,建立直角坐标轴。
若当前数字大于了查找数,查找往上移一位。
若当前数字小于了查找数,查找往右移一位。
*/
var searchMatrix = function(matrix, target) {
let x = matrix.length-1,y = 0
while(x>=0 && y<matrix[0].length){
if(matrix[x][y]===target){
return true
}else if(matrix[x][y]>target){
x--
}else{
y++
}
}
return false
};
javascript 二分法
/**
* @param {number[][]} matrix
* @param {number} target
* @return {boolean}
*/
var searchMatrix = function(matrix, target) {
let m = matrix.length,n=matrix[0].length
let low = 0,high = m*n-1
while(low<=high){
let mid = Math.floor((high-low)/2)+low //中位
let x = matrix[Math.floor(mid/n)][mid%n] //所在的值
if(x<target){
low = mid+1
}else if(x>target){
high = mid-1
}else{
return true
}
}
return false
};
Typescript 以上两种也可以改为ts
function searchMatrix(matrix: number[][], target: number): boolean {
let x: number = matrix.length - 1, y:number = 0
while (x >= 0 && y < matrix[0].length) {
if (matrix[x][y] === target) {
return true
} else if (matrix[x][y] > target) {
x--
} else {
y++
}
}
return false
};
python 暴力解法
class Solution(object):
def searchMatrix(self, matrix, target):
for i in range(len(matrix)):
for j in range(len(matrix[0])):
if matrix[i][j]==target:
return True
return False
python any函数
any() 函数用于判断给定的可迭代参数 iterable 是否全部为 False,则返回 False,如果有一个为 True,则返回 True。元素除了是 0、空、FALSE 外都算 TRUE。
语法
def any(iterable):
for element in iterable:
if element:
return True
return False
解法
class Solution(object):
def searchMatrix(self, matrix, target):
return any(target in row for row in matrix)
笨阶乘
通常,正整数 n 的阶乘是所有小于或等于 n 的正整数的乘积。例如,factorial(10) = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1。
相反,我们设计了一个笨阶乘 clumsy:在整数的递减序列中,我们以一个固定顺序的操作符序列来依次替换原有的乘法操作符:乘法(*),除法(/),加法(+)和减法(-)。
例如,clumsy(10) = 10 * 9 / 8 + 7 - 6 * 5 / 4 + 3 - 2 * 1。然而,这些运算仍然使用通常的算术运算顺序:我们在任何加、减步骤之前执行所有的乘法和除法步骤,并且按从左到右处理乘法和除法步骤。
另外,我们使用的除法是地板除法(floor division),所以 10 * 9 / 8 等于 11。这保证结果是一个整数。
实现上面定义的笨函数:给定一个整数 N,它返回 N 的笨阶乘。
示例 1:
输入:4
输出:7
解释:7 = 4 * 3 / 2 + 1
示例 2:
输入:10
输出:12
解释:12 = 10 * 9 / 8 + 7 - 6 * 5 / 4 + 3 - 2 * 1
提示:
1 <= N <= 10000
-2^31 <= answer <= 2^31 - 1 (答案保证符合 32 位整数。
GOLang
func clumsy(N int) int {
if N == 1 {
return 1
} else if N == 2 {
return 2
} else if N == 3 {
return 6
} else if N == 4 {
return 7
}
if N%4 == 0 {
return N + 1
} else if N%4 <= 2 {
return N + 2
} else {
return N - 1
}
}
javascript
/**
* @param {number} N
* @return {number}
*/
var clumsy = function (N) {
if (N === 1) {
return 1
} else if (N === 2) {
return 2
} else if (N === 3) {
return 6
} else if (N === 4) {
return 7
}
if (N % 4 === 0) {
return N + 1
} else if (N % 4 <= 2) {
return N + 2
} else {
return N - 1
}
};
python
class Solution(object):
def clumsy(self, N):
"""
:type N: int
:rtype: int
"""
if N == 1:
return 1
elif N == 2:
return 2
elif N == 3:
return 6
elif N == 4:
return 7
if N % 4 == 0:
return N + 1
elif N % 4 <= 2:
return N + 2
else:
return N - 1
typescript
function clumsy(N: number): number {
if (N === 1) {
return 1
} else if (N === 2) {
return 2
} else if (N === 3) {
return 6
} else if (N === 4) {
return 7
}
if (N % 4 === 0) {
return N + 1
} else if (N % 4 <= 2) {
return N + 2
} else {
return N - 1
}
};
17.21. 直方图的水量
难度:[困难]
给定一个直方图(也称柱状图),假设有人从上面源源不断地倒水,最后直方图能存多少水量?直方图的宽度为 1。
上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的直方图,在这种情况下,可以接 6 个单位的水(蓝色部分表示水)。 感谢 Marcos 贡献此图。
示例:
输入: [0,1,0,2,1,0,1,3,2,1,2,1]
输出: 6
【思路】动态规划
1.记录height中的每个元素,从左向右扫描并记录右边的最大高度;
2.记录height中的每个元素,从右向左扫描并记录右边的最大高度;
3.将左右位置元素对比取最小的元素,减去数组当前元素的高度。
从左向右扫描并记录右边的最大高度
从右向左扫描并记录右边的最大高度
取高度最小值
go
func trap(height []int) int {
n := len(height)
if n == 0 {
return 0
}
//记录左边每个元素最大高度
leftMax := make([]int, n)
leftMax[0] = height[0]
for i := 1; i < n; i++ {
leftMax[i] = max(leftMax[i-1], height[i])
}
//记录左边每个元素最大高度
rightMax := make([]int, n)
rightMax[n-1] = height[n-1]
for i := n - 2; i >= 0; i-- {
rightMax[i] = max(rightMax[i+1], height[i])
}
fmt.Println(leftMax, rightMax)
ret := 0
for j := 0; j < n; j++ {
ret += (min(leftMax[j], rightMax[j]) - height[j])
}
return ret
}
//由于Go语言里面没有max(),min()需要自己实现一个
func max(a, b int) int {
if a-b > 0 {
return a
}
return b
}
func min(a, b int) int {
if a-b > 0 {
return b
}
return a
}
Javascript
var trap = function (height) {
let len = height.length
if (len === 0) return 0
//记录左边每个矩形最大高度
let left = Array(len).fill(0)
left[0] = height[0]
for (let i = 1; i < len; ++i) {
left[i] = Math.max(left[i - 1], height[i])
}
//记录右边每个矩形最大高度
let right = Array(len).fill(0)
right[len - 1] = height[len - 1]
for (let i = len - 2; i >= 0; --i) {
right[i] = Math.max(right[i + 1], height[i])
}
//记录结果
let ret = 0
for (let i = 0; i < len; ++i) {
//左右对比取最小边界,减去当前矩形高度
ret += Math.min(left[i], right[i]) - height[i]
}
return ret
};
Typescript
function trap(height) {
var len = height.length;
if (len === 0)
return 0;
//记录左边每个矩形最大高度
var left = Array(len);
left[0] = height[0];
for (var i = 1; i < len; ++i) {
left[i] = Math.max(left[i - 1], height[i]);
}
//记录右边每个矩形最大高度
var right = Array(len);
right[len - 1] = height[len - 1];
for (var i = len - 2; i >= 0; --i) {
right[i] = Math.max(right[i + 1], height[i]);
}
//记录结果
var ret = 0;
for (var i = 0; i < len; ++i) {
//左右对比取最小边界,减去当前矩形高度
ret += Math.min(left[i], right[i]) - height[i];
}
return ret;
}
python
class Solution(object):
def trap(self, height):
"""
:type height: List[int]
:rtype: int
"""
if not height:
return 0
# 数组长度
n = len(height)
# 记录左边每个矩形最大高度
left = [0]*n
left[0] = height[0]
for i in range(1,n):
left[i] = max(left[i - 1], height[i])
# 记录右边每个矩形最大高度
right = [0]*n
right[n - 1] = height[n - 1]
for i in range(n-2,-1,-1):
right[i] = max(right[i + 1], height[i])
# 记录结果
ret = sum(min(left[i], right[i]) - height[i] for i in range(n))
return ret
继续加油!
有疑问加站长微信联系(非本文作者)