Golang语言[6] 递增的三元子序列/笨阶乘/矩阵查找/直方图的水量 |Go主题月

90d1c7657a694816e344912feddf040f.jpg

递增的三元子序列

给你一个整数数组 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。

图片.png

上面是由数组 [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.将左右位置元素对比取最小的元素,减去数组当前元素的高度。

从左向右扫描并记录右边的最大高度
image
从右向左扫描并记录右边的最大高度
image
取高度最小值
image

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

继续加油!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容