数据结构与算法之字符串: LeetCode 696. 计数二进制子串 (Ts, Py, Go, Java版)

7系列ZYNQ硬件调试:Vitis无法识别ARM DAP的排查与解决 本文针对7系列ZYNQ开发中Vitis无法识别ARM DAP的典型硬件调试问题,提供了系统性的排查与解决方案。文章深入剖析了问题本质,指出ARM DAP无法访问的核心原因在于PS部分的电源、时钟或复位等硬件基础条件未满足,并重点强调了PS参考时钟(如33.333MHz晶振)的完整性是关键排查点。通过从电源完整性、时钟与复位信号到JTAG连接与焊接的逐步硬件排查,并结合软件配置交叉验证,为开发者提供了清晰的故障定位思路与实战指南。 阅读详情

计数二进制子串

  • https://leetcode.cn/problems/count-binary-substrings/

描述

  • 给定一个字符串 s,统计并返回具有相同数量 0 和 1 的非空(连续)子字符串的数量,并且这些子字符串中的所有 0 和所有 1 都是成组连续的。

  • 重复出现(不同位置)的子串也要统计它们出现的次数。

示例 1:

输入:s = "00110011"
输出:6
解释:6 个子串满足具有相同数量的连续 1 和 0 :"0011"、"01"、"1100"、"10"、"0011" 和 "01" 。
注意,一些重复出现的子串(不同位置)要统计它们出现的次数。
另外,"00110011" 不是有效的子串,因为所有的 0(还有 1 )没有组合在一起。

示例 2:

输入:s = "10101"
输出:4
解释:有 4 个子串:"10"、"01"、"10"、"01" ,具有相同数量的连续 1 和 0 。

提示

  • 1 <= s.length <= 10510^5105
  • s[i] 为 ‘0’ 或 ‘1’

Typescript 版算法实现

1 )方案1

// leetcode 大规模数据不通过

function countBinarySubstrings(s: string): number {
  // 建立数据结构,队列,用于保存数据
  const r = []
  // 给定任意子输入都返回第一个符合条件的子串
  const match = (s:string) => {
    // 找到含有0或1一次或多次的匹配字符串
    const j:string = s.match(/^(0+|1+)/)?.[0] ?? ''

    // 生成第一个字符异或得到相反的字符,并且长度和匹配字符串保持一致
    const o:string = (Number(j[0]) ^ 1).toString().repeat(j.length)
    // 构造出新的正则,用于过滤当前切片的规则,注意这里的 ^ 开始很重要
    const reg = new RegExp(`^(${j}${o})`)
    // 符合条件,拿到 () 中的匹配字符串
    if (reg.test(s)) {
      return RegExp.$1 // 得到第 1 个子表达式相匹配的文本
    }
    return ''
  }
  // 通过for循环控制程序运行的流程
  for (let i = 0, len = s.length - 1; i < len; i++) {
  	// i 递增,进行切片处理,每次 slice 都会向后移动一位
  	// 注意 slice 左闭右开,参数为:[start, end]
    const sub = match(s.slice(i))
    if (sub) {
      r.push(sub)
    }
  }
  return r.length
};
console.log(countBinarySubstrings('00110011'))

思路:

  • 对字符串做切片处理,从第一位到倒数第二位,左闭右开,此处需要一个for循环
  • 对每一个切片进行单一处理,每个切片只找一个,避免循环到后面出现重复
  • 将找到符合规则的切片存入数组
  • 统计最终数组的长度,即答案

注意:

  • 这个方案在 leetcode上是通不过的,错误发生在 new RegExp 的时候,错误信息是:SyntaxError: Invalid regular expression,Regular expression too large 这个错误在实际应用场景中是不会出现的,用例有些极端了
  • 拼接出的正则表达式 ^(j{j}j{o}) 会超出引擎的处理限制,导致 RangeError 或性能崩溃

2 )方案2

function countBinarySubstrings2(s: string): number {
  let count:number = 0 // 用于统计最终符合要求的长度
  let last:string = '_'; // 上一个字符初始化
  let pre:number = 0; // 上一次统计次数
  let cur:number = 0; // 当前字符出现的统计次数
  let i:number = 0; // 当前循环次数
  while(i <= s.length) {
    const c:string = s[i]; // 获取当前切片字符串
    // 第一次一定会执行,last 就会被重新赋值,last 保留的是前一个字符
    // 只有遇到新的值时,last 才会变成当前新值,这个if里面对当前字符 c 进行统计次数
    if(last !== c) {
        // 遇到下一个不同字符更新, 用pre保留cur值
        last = c; // 保留当前字符串
        count += Math.min(pre, cur); // 比较前2个不同字符出现次数的最小值
        pre = cur; // pre 保留前一个字符出现的次数
        cur = 0; // 如果不相等,cur 统计次数清零
        // console.log('count;', count);
    }
    cur ++; // 统计当前字符出现的次数
    i ++; // 本次循环次数+1
  }
  return count;
}
console.log(countBinarySubstrings2('00110011'));
  • 这是官方精选解题方案
    • https://leetcode.cn/problems/count-binary-substrings/solution/count-binary-substrings-by-ikaruga/
  • 这样前面是连续 0/1 后面是连续 1/0 的数据
  • 每次符合的字符取决于前面 0/1 的个数和后面 1/0 的个数,即 min(pre, cur)
  • 遍历时,当数字再一次改变时(或到达结尾时), 意味着一段结束,并能得到这一段前面和后面数字的个数
  • 每次符合条件,并采用最小值,即可得到当前可用的统计答案
  • 再将结果累加到 count 上就得到所有的可能结果

3 )方案3

function countBinarySubstrings3(s: string): number {
    // index 是当前循环次数, n 是字符串长度, last是上一次统计数量, ans 是最终统计结果
    let index = 0, n = s.length, last = 0, ans = 0;
    while (index < n) {
        const c = s.charAt(index); // c 是当前字符串
        let count = 0; // 每次count都重置一下
        // 统计当前相同字符串的结果
        while (index < n && s.charAt(index) === c) {
            ++index;
            ++count;
        }
        ans += Math.min(count, last); // 从 count 和 last 找到最小的统计,取最小值
        last = count; // 缓存 count统计
    }
    return ans;
};
console.log(countBinarySubstrings3("00110011"));
  • 此方案为官方题解,参考:
  • https://leetcode.cn/problems/count-binary-substrings/solutions/367704/ji-shu-er-jin-zhi-zi-chuan-by-leetcode-solution/
  • 此方案与上述方案2有异曲同工之妙,两者原理相似

Python3 版算法实现

1 )方案1

class Solution:
    def countBinarySubstrings(self, s: str) -> int:
        count = 0  # 用于统计最终符合要求的长度
        last = '_'  # 上一个字符初始化
        pre = 0  # 上一次统计次数
        cur = 0  # 当前字符出现的统计次数
        i = 0  # 当前循环次数
        while i <= len(s):
            if i == len(s):
                c = None
            else:
                c = s[i]  # 获取当前切片字符串

            # 第一次一定会执行,last 就会被重新赋值,last 保留的是前一个字符
            # 只有遇到新的值时,last 才会变成当前新值,这个if里面对当前字符 c 进行统计次数
            if last != c:
                # 遇到下一个不同字符更新, 用pre保留cur值
                last = c  # 保留当前字符串
                count += min(pre, cur)  # 比较前2个不同字符出现次数的最小值
                pre = cur  # pre 保留前一个字符出现的次数
                cur = 0  # 如果不相等,cur 统计次数清零

            cur += 1  # 统计当前字符出现的次数
            i += 1  # 本次循环次数+1
        return count

2 )方案2

class Solution:
    def countBinarySubstrings(self, s: str) -> int:
        index = 0  # 当前循环次数
        n = len(s)  # 字符串长度
        last = 0  # 上一次统计数量
        ans = 0  # 最终统计结果

        while index < n:
            c = s[index]  # 获取当前字符串
            count = 0  # 重置每次统计的计数

            # 统计当前相同字符串的结果
            while index < n and s[index] == c:
                index += 1
                count += 1

            ans += min(count, last)  # 从 count 和 last 找到最小的统计值,取最小值进行累加
            last = count  # 缓存 count 统计值

        return ans

Golang 版算法实现

1 )方案1

func countBinarySubstrings(s string) int {
    count := 0      // 用于统计最终符合要求的长度
    last := byte('_')  // 上一个字符初始化
    pre := 0        // 上一次统计次数
    cur := 0        // 当前字符出现的统计次数
    i := 0          // 当前循环次数

    for i <= len(s) {
        var c byte
        if i == len(s) {
            c = 0
        } else {
            c = s[i] // 获取当前切片字符串
        }

        // 第一次一定会执行,last 就会被重新赋值,last 保留的是前一个字符
        // 只有遇到新的值时,last 才会变成当前新值,这个if里面对当前字符 c 进行统计次数
        if last != c {
            // 遇到下一个不同字符更新, 用pre保留cur值
            last = c  // 保留当前字符串
            count += min(pre, cur) // 比较前2个不同字符出现次数的最小值
            pre = cur // pre 保留前一个字符出现的次数
            cur = 0   // 如果不相等,cur 统计次数清零
        }

        cur++  // 统计当前字符出现的次数
        i++    // 本次循环次数+1
    }

    return count
}

// 辅助函数:返回两个整数中较小的一个
func min(a, b int) int {
    if a < b {
        return a
    }
    return b
}

2 )方案2

func countBinarySubstrings(s string) int {
    index := 0     // 当前循环次数
    n := len(s)    // 字符串长度
    last := 0      // 上一次统计数量
    ans := 0       // 最终统计结果

    for index < n {
        c := s[index]  // 获取当前字符
        count := 0     // 重置每次统计的计数

        // 统计当前相同字符串的结果
        for index < n && s[index] == c {
            index++
            count++
        }

        ans += min(count, last) // 从 count 和 last 找到最小的统计值,取最小值进行累加
        last = count            // 缓存 count 统计值
    }

    return ans
}

// 辅助函数:返回两个整数中较小的一个
func min(a, b int) int {
    if a < b {
        return a
    }
    return b
}

Java 版算法实现

1 ) 暴力枚举与正则匹配法 (Brute Force with Regular Expression)

// 下面的正则算法超出时间限制!

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main1 {

    public static int countBinarySubstrings(String s) {
        List<String> r = new ArrayList<>();
        for (int i = 0; i < s.length() - 1; i++) {
            String sub = match(s.substring(i));
            if (!sub.isEmpty()) {
                r.add(sub);
            }
        }
        return r.size();
    }

    private static String match(String s) {
        Pattern p = Pattern.compile("^(0+|1+)");
        Matcher m = p.matcher(s);
        if (!m.find()) {
            return "";
        }

        String j = m.group(1);
        char c = j.charAt(0) == '0' ? '1' : '0';
        String o = String.valueOf(c).repeat(j.length());

        Pattern reg = Pattern.compile("^(" + j + o + ")");
        Matcher m2 = reg.matcher(s);
        if (m2.find()) {
            return m2.group(1);
        }

        return "";
    }

    public static void main(String[] args) {
        System.out.println(countBinarySubstrings("00110011"));
    }
}

算法说明

  1. 遍历字符串的每个可能起点,通过 substring 截取后缀子串。
  2. 使用正则表达式提取后缀开头的连续相同字符段(如 000)及其长度。
  3. 动态构造“等长且字符相反”的正则表达式(如 ^000111),验证并提取符合条件的子串。
  4. 将所有匹配到的有效子串存入列表,最终返回列表的大小作为结果。

无法通过的 Case 解释

  1. 正则表达式超限报错:当输入包含极长的连续相同字符(例如几千个 '1')时,动态拼接出的正则表达式长度会达到上万字符,超出 Java 正则引擎的处理限制,导致 PatternSyntaxException 或底层栈溢出。
  2. 超时 (Time Limit Exceeded):s.substring(i) 每次都会创建新的字符串对象,结合正则表达式的编译与匹配,整体时间复杂度接近 O(N2)O(N^2)O(N2)。对于长测试用例,执行时间会远超限制。
  3. 内存溢出 (Memory Limit Exceeded):代码将所有匹配到的子串字符串都保存到了 ArrayList 中。题目仅要求返回数量,这种存储方式会造成极大的额外空间开销。

2 ) 一次遍历与分组统计法 (Linear Scan and Group Counting)

public class Main2 {
    public static int countBinarySubstrings(String s) {
        int count = 0; // 用于统计最终符合要求的长度
        char last = '_'; // 上一个字符初始化
        int pre = 0; // 上一次统计次数
        int cur = 0; // 当前字符出现的统计次数
        int i = 0; // 当前循环次数

        while (i <= s.length()) {
            char c = i < s.length() ? s.charAt(i) : ' '; // 获取当前字符,越界时赋空格
            // 第一次一定会执行,last 就会被重新赋值,last 保留的是前一个字符
            // 只有遇到新的值时,last 才会变成当前新值,这个if里面对当前字符 c 进行统计次数
            if (last != c) {
                // 遇到下一个不同字符更新,用pre保留cur值
                last = c; // 保留当前字符串
                count += Math.min(pre, cur); // 比较前2个不同字符出现次数的最小值
                pre = cur; // pre 保留前一个字符出现的次数
                cur = 0; // 如果不相等,cur 统计次数清零
            }
            cur++; // 统计当前字符出现的次数
            i++; // 本次循环次数+1
        }
        return count;
    }

    public static void main(String[] args) {
        System.out.println(countBinarySubstrings("00110011"));
    }
}

算法说明

  1. 状态初始化:使用 pre 记录前一组连续字符的长度,cur 记录当前组连续字符的长度,count 记录最终结果。
  2. 线性扫描:遍历字符串,逐个字符判断。若当前字符与前一个字符相同,则当前组的连续长度 cur 加 1。
  3. 分组切换:当遇到不同的字符(或到达字符串末尾触发边界条件)时,说明当前连续字符组结束。此时,符合条件的子串数量取决于相邻两组长度的较小值,即累加 Math.min(pre, cur) 到 count 中。
  4. 状态更新:将 pre 更新为当前的 cur,并将 cur 重置为 0,开始统计新一组连续字符的长度。
  5. 返回结果:遍历结束后,直接返回累加的 count。该算法时间复杂度为 O(N)O(N)O(N),空间复杂度为 O(1)O(1)O(1),完美避免了正则和字符串切片带来的性能问题。

3 ) 游程统计法 (Run-Length Encoding / Consecutive Segment Counting)

public class Main3 {
    public static int countBinarySubstrings3(String s) {
        // index 是当前循环次数, n 是字符串长度, last是上一次统计数量, ans 是最终统计结果
        int index = 0, n = s.length(), last = 0, ans = 0;
        while (index < n) {
            char c = s.charAt(index); // c 是当前字符串
            int count = 0; // 每次count都重置一下
            // 统计当前相同字符串的结果
            while (index < n && s.charAt(index) == c) {
                ++index;
                ++count;
            }
            ans += Math.min(count, last); // 从 count 和 last 找到最小的统计,取最小值
            last = count; // 缓存 count统计
        }
        return ans;
    }

    public static void main(String[] args) {
        System.out.println(countBinarySubstrings3("00110011"));
    }
}

算法说明

  1. 外层循环控制分组:使用 index 遍历字符串,每次获取当前字符 c 作为当前连续段的基准字符。
  2. 内层循环统计长度:通过内层 while 循环,只要字符与 c 相同就继续向后遍历,累加当前连续字符的长度 count,并同步推进 index。
  3. 计算有效子串:内层循环结束时,当前连续段统计完毕。将当前段长度 count 与上一段长度 last 取较小值,累加到最终结果 ans 中。
  4. 状态传递:将当前段长度 count 赋值给 last,作为下一段比较的基准,随后进入下一次外层循环处理新的字符段。
  5. 该算法通过内层循环直接跳过相同字符,减少了外层循环的判断次数,时间复杂度为 O(N)O(N)O(N),空间复杂度为 O(1)O(1)O(1),逻辑非常清晰。
元数据治理实战:构建企业数据地图与血缘体系 元数据(Metadata)是描述数据的数据,是你能了解“数据是怎么来的”、“它是做什么的”、“能不能用”的基础信息。📌 举个例子:order_idstringods_order定义:平台内用户在订单系统中产生的唯一订单编号更新时间:每天凌晨 2 点,由 Airflow 调度任务生成所属人:张三(数据开发部)🔍 这些信息本身不直接参与计算,但它们是数据可管理、可追踪、可评估的基础。模块实战建议元数据类型技术 + 业务 + 操作元数据三类统一治理治理路径。 阅读详情

相关推荐

AD620仪表放大器模组实战:从调零到信号放大的完整指南

本文详细介绍了AD620仪表放大器模组的实战应用,从调零到信号放大的完整指南。AD620模组以其专业级性能和易用性成为微弱信号放大的首选,集成了AD620芯片、LM358运放和7660电源转换芯片。文章提供了调零技巧、增益设置方法以及单端与差分输入的正确连接方案,并通过心电信号采集和称重传感器等实际案例展示了其广泛应用。

weixin_29290379的博客 377

数据结构与算法笔记:字典序最大问题分析

字典序最大问题 问题描述 给定一个1到n的排列(无序状态的),依次插入到栈中,在每时每刻都可以多次从栈中弹出栈顶 问:应如何使得弹出栈顶的序列的字典序最大,并输出这个序列 问题分析 什么是字典序 比如两个序列:5,4,3,2,1和1,2,3,4,5 这两个中第一个的字典序最大 每个位置上的数字比其他序列上同一位置的数字要大 比如:第一位置中5比1大,第二位置中4比2大这样 即:字典序最大 = 从左向右看这个序列,每个数字都尽量大 题目给定一个1到n的排列,每个数字只出现一次 要使出栈的字典序最大

Wang的专栏 4393

Ego-Planner实战避坑指南:从环境搭建到仿真运行

本文详细介绍了在Windows系统下,通过WSL2搭建Ego-Planner无人机路径规划算法开发环境的完整流程与实战避坑指南。内容涵盖ROS Noetic安装、第三方依赖库(如Ceres Solver)编译冲突解决、Realsense SDK版本降级处理,以及Gazebo仿真与真机调试的常见问题,旨在帮助开发者高效完成环境配置并成功运行仿真。

weixin_29232507的博客 700

数据结构与算法笔记:农夫过河问题python3实现

问题描述 农夫(Human)过河。一个农夫带着一只狼(Wolf),一只羊(Sheep)和一些菜(Vegetable)过河。河边只有一条船,由于船太小,只能装下农夫和他的一样东西。在无人看管的情况下,狼要吃羊,羊要吃菜,请问农夫如何才能使三样东西平安过河? 要求: 输出一行,为最终的过河方式,方案格式为 过河人员、回来人员、过河人员、回来人员、…、过河人员。 过去和回来的人员之间,用空格隔开。 以四...

Wang的专栏 3374

ANSYS Help USER300

USER 300概述单元描述输入数据假设与限制条件 概述 单元描述 Mechanical APDL提供了一种方便的方法来创建自定义的单元,命名为USER300,可以创建几乎任何单元类型。 UserElem子程序为Mechanical APDL在单元类型创建上提供了一个接口,可传递用户自定义单元创建时所需的所有数据,然后从自定义单元返回所有数据和结果,以更新数据库和文件。因为通过接口可以访问数据库和文件信息,所以很少需要了解Mechanical APDL数据库程序和文件结构。该接口还提供了获取Mechanic

weixin_47019765的博客 2235

【LPDDR4 - 学习二】LPDDR4 介绍 ——LPDDR4 芯片引脚说明解析

本文系统解析了LPDDR4内存芯片的引脚定义与特性,重点介绍了272球POPFBGA封装的双通道架构。内容涵盖电源管理(三级供电架构与上电时序)、控制信号(差分时钟与复用命令总线)、数据接口(16位双向数据总线与选通信号)以及校准复位等核心模块。通过表格详细列明了各引脚电压范围、功能定义及工程注意事项,并附有典型封装球位分布图。全文基于JEDEC标准,为移动设备内存设计提供全面的硬件参考,特别强调电源时序控制、信号完整性及抗干扰设计等关键点。

zap15622077817的博客 2648

数据结构与算法笔记:计算思维之经典农夫过河问题C++实现

农夫、羊、狼、菜的过河问题 问题描述 角色:农夫,羊,狼,菜 条件1:船很小,只能装下农夫和其他一个角色 条件2:无人看管,羊吃菜,狼吃羊 问:如何让其他三种角色被农夫平安带着过河? 相关分析 我们可以先用人脑尝试一下相关渡河策略 1 ) 先渡狼,人回来再渡菜,人回来再渡羊 2 ) 先渡菜,人回来再渡狼,人回来再渡羊 以上两种很好想到,而且我们可以知道羊这种角色是不能先渡河过去的,羊需要最后再渡 如果先渡了羊了,之后再渡任何其他角色,都要将羊带回来 可以参考小游戏:http://gameschool

Wang的专栏 3312

OpenAI Function Calling 实战:让 Agent 自动调用外部 API 接口

在 2023 年 6 月之前,大语言模型(LLM)的能力边界是清晰的:它能说会道,能写诗作赋,也能帮你润色文案。但如果你问它"北京现在天气怎么样",它要么答不上来,要么基于过时的训练数据给你一个错误答案。原因很简单——LLM 的训练数据是有截止日期的,它活在"过去"。2023 年 6 月,OpenAI 在 GPT-4 的更新中引入了 Function Calling 功能,彻底改变了这一局面。Function Calling(也叫 Tool Use 或工具调用)是一种让 LLM 与外部系统交互的机制。

2201_76125393的博客 89

数据结构与算法笔记:图搜索之DFS详解

图搜索 Graph Search 图搜索的分类 BFS广度优先(宽搜) DFS深度优先(深搜) !!!本文详解!!! 深度优先搜索DFS 深度优先遍历DFS, 这个策略其实是非常stupid or simple的,比BSF要简单的多 同样,我们可以通过一个故事来开始 在古希腊神话中, Ariadne是Crete的国王Minos的公主,她给忒修斯(Theseus)一个线团 使得忒修斯成功进入迷宫杀死牛头怪兽,但事后忒修斯抛弃了她 这是一个有道德意义的故事又或者存在不同的版本, 但不是我们的研究的对象

Wang的专栏 3118

C# NX二次开发-查找连续倒圆角面

可以通过ufun函数 UF_MODL_ask_face_type 和 UF_MODL_ask_face_props 可判断处理选择相应的一组圆角面。在QQ群里有人问怎么通过一个选择一个倒圆角面来自动选中一组倒圆角面。这个是初步思路,如果有更好的思路可回复讨论一下。

fhqiwmc的博客 621

YOLOv13保姆级教程+AKConv模块:可变形卷积+自适应核优化,mAP提升3.23%,召回率&mAP50~95显著提升(论文涨点模块已验证)

本文介绍了一种改进的YOLOv13-AKConv模型,通过引入AKConv模块显著提升了目标检测性能。实验结果表明,优化后的模型(绿色曲线)相比原模型(蓝色曲线)在mAP指标上提升了3.23个点,同时召回率、mAP50-95等指标均有明显提升。作者详细阐述了模型移植过程,包括创建yolov13-AKConv.yaml配置文件,修改tasks.py和modules/init.py文件,以及实现AKConv模块的核心代码。该模块采用可变形卷积思想,通过动态生成采样点位置来增强特征提取能力,并集成了BN和SiLU

FJN110的博客 2611

数据结构与算法笔记:计算思维之人鬼渡河问题

人鬼渡河问题 1 ) 问题描述 目标:将东岸的3人3鬼通过一只小船安全转移到西岸,希望摆渡次数尽可能少 条件 船的容量有限,一次最多只能坐2人(或2鬼或1人1鬼) 无论是在河的东岸还是在河的西岸,一旦鬼数多于人数,则人将被鬼吃掉 怎样渡河的大权掌握在人的手中 说明:划船的时间忽略不计。船一靠岸即将船与岸视为一体,人和鬼即使还没有下 船也视为已上岸 任务:编写程序,求出一种渡河方案 备注:图片托管于github,请确保网络的可访问性 2 ) 分析 目标是找

Wang的专栏 2447

【LAMMPS学习】五、LAMMPS命令(1) LAMMPS 输入脚本

本部分描述了 LAMMPS 输入脚本的格式以及其中的命令如何用于定义 LAMMPS 模拟。主要包括以下内容。

荷塘阅色 2645

数据结构与算法之二叉树: LeetCode 701. 二叉搜索树中的插入操作 (Ts版)

1 ) 方案1:模拟。2 ) 方案2:递归。

Wang的专栏 2270

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

数据结构与算法笔记:计算思维之下楼梯台阶和象棋跳马问题

下台阶问题 1 ) 问题描述 从楼上走到楼下共有 h 个台阶,每一步有三种走法 走一个台阶; 走二个台阶; 走三个台阶。 问:一共可以走出多少种方案? 即共要多少步? 每一步走几级台阶? 2 ) 分析 初始思路 我们根据题目给定的场景,先简单模拟一下,设定 h=4h=4h=4 备注:图片托管于github,请确保网络的可访问性 如上图所示, 这里有4阶楼梯, 红色数字代表每一步走几级台阶 这里枚举了4层台阶的所有可能情况, 但是不管具体有几级台阶,下

Wang的专栏 2111

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Python笔记:滑动验证码的识别算法

概述 用程序识别极验滑动验证码的验证,包括分析识别思路、识别缺口位置、生成滑块拖动路径、模拟实现滑块拼合通过验证等步骤。 准备工作 使用Python库是Selenium,浏览器为Chrome。请确保已安装Selenium库和ChromeDriver浏览器驱动。 关于极验滑动验证码: 极验滑动验证码官网为:http://www.geetest.com/ 验证方式为拖动滑块拼合图像,若图像完全拼合...

Wang的专栏 2103

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

数据结构与算法之堆: LeetCode 295. 数据流的中位数 (Ts版)

/ 返回 1.5 ((1 + 2) / 2)中位数是有序整数列表中的中间值。如果列表的大小是偶数,则没有中间值,中位数是两个中间值的平均值。3 ) 方案3:有序集合 + 双指针。2 ) 方案2:优先队列-优化版。1 ) 方案1:优先队列。

Wang的专栏 1907

数据结构与算法笔记:计算思维之谁做的好事与刑侦作案问题

谁做的好事 清华附中有四位同学中的一位做了好事,不留名,表扬信来了之后,校长问这四位是谁做的好事。 A说:不是我。 B说:是C。 C说:是D。 D说:他胡说。 已知:三个人说的是真话,一个人说的是假话。 现在请你根据这些信息,编写程序找出做了好事的人。 分析 将四个人说的四句话(自然语言)转换成计算机可以计算的式子, 可使用循环枚举的方式来判断 (1) 思路一:通过字符表示人 先定义一个字符变量 thisman 表示要寻找的做了好事的人的“名字(代号)”(A、B、C、D),即 char this

Wang的专栏 1829

数据结构与算法笔记:图搜索之BFS详解

图搜索 Graph Search 图搜索的分类 BFS广度优先(宽搜) DFS深度优先(深搜) 广度优先搜索BFS 我们可以用比喻来说明广度优先搜索算法 在一片草木枯黄的深秋草原上,在草原的某一处出现了一处野火 一开始的时候野火集中于一点之上,在这点野火耗尽当前植被变成灰烬之前点燃了周围的植被 比如节点s是初始火种,假设我们手中有一个秒表,每过1秒,我们的大火会向外迈进一步 这个过程只能向外,不能向内,因为只能点燃植被,不能把灰烬点燃 蓝色的点是即将变为灰烬的点,红色的点是刚被点燃的点,灰色的圆形或

Wang的专栏 1791

数据结构与算法之动态规划: LeetCode 1494. 并行课程 II (Ts版)

给你一个整数 n 表示某所大学里课程的数目,编号为 1 到 n ,数组 relations 中, relations[i] = [xi, yi] 表示一个先修课的关系,也就是课程 xi 必须在课程 yi 之前上。解释:上图展示了题目输入的图。一个最优方案是:第一学期上课程 2 和 3,第二学期上课程 4 ,第三学期上课程 1 ,第四学期上课程 5。然后第二个学期上课程 1 ,第三个学期上课程 4。在一个学期中,你 最多 可以同时上 k 门课,前提是这些课的先修课在之前的学期里已经上过了。

Wang的专栏 1749

数据结构与算法笔记:求直方图最大面积算法分析

直方图最大面积 问题描述 有n列的直方图,第j列高度为hjh_jhj​, 求一个面积最大的子矩阵 备注:图片托管于github,请确保网络的可访问性 格式要求 输入第一行正整数n,第二行n个空格隔开的非负整数 数据范围: 所有直方图的列不会超过30000 关键算法实现 1 ) 算法1:时间复杂度为: O(n3)O(n^3)O(n3)的实现 分析 矩形面积为底和高的乘积 底部从a到b,那么底边长为: b-a+1 高为:min{hi∣a≤i≤b}min \{h

Wang的专栏 1664

数据结构与算法之LRU: 实现 LRU 缓存算法功能 (Ts, Py, Go版)

LRU - Lease Recently Used 最近使用如果内存优先,只缓存最近使用的,删除 ‘沉睡’ 数据核心 api: get set分析。

Wang的专栏 1599

数据结构与算法之贪心: LeetCode 455. 分饼干 (Ts, Py, Go版)

对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j]。如果 s[j] >= g[i],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。2 )排序 + 双指针 + 贪心。1 )排序 + 遍历。

Wang的专栏 1566

动态规划(Dynamic Programming)详解:从入门到 LeetCode Hot 100

将一个复杂问题拆分成多个规模更小的子问题,通过保存子问题的计算结果,避免重复计算,最终得到原问题的答案。先看一个经典问题。dp[i] = 以第 i 个元素结尾的最优结果例如最长递增子序列。最长递增子序列不一定以最后一个元素结尾,因此必须遍历整个数组取最大值。dp[i] = 前 i 个元素的最优结果这种情况下,最终答案通常就是dp[n]。关键在于理解 dp 数组的定义。动态规划的核心并不是背诵某个固定模板,而是建立正确的状态定义,并通过状态转移方程解决问题。dp[i] 或 dp[i][j] 表示什么?

zengjiajun2006的博客 693

LeetCode 每日一题 2026/11/2-2026/11/8

记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步

AlphaTao的博客 186

LeetCode 面试经典 150_多维动态规划_交错字符串(97_C++_中等)

LeetCode 面试经典 150_多维动态规划_交错字符串(97_C++_中等) 题目描述: 给定三个字符串 s1、s2、s3,请你帮忙验证 s3 是否是由 s1 和 s2 交错 组成的。 两个字符串 s 和 t 交错 的定义与过程如下,其中每个字符串都会被分割成若干 非空 子字符串: - s = s1 + s2 + ... + sn - t = t1 + t2 + ... + tm - |n - m| <= 1 - 交错 是 s1 + t

huayimenghan的博客 212
上一篇: 数据结构与算法之字符串: LeetCode 557. 反转字符串中的单词 III (Ts, Py, Go, Java版)
下一篇: 数据结构与算法之字符串: LeetCode 20. 有效的括号 (Ts, Py, Go, Java版)
Wang's Blog
博客等级 码龄12年 7433粉丝 2421原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值