数据结构与算法之堆: 实现最大堆类的两种方式及实现堆排序 (Ts, Py, Go版)

力扣(Leetcode)第1题:两数之和(C语言版本) 题目: 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出和为目标值 target 的那两个整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回答案。 示例 1: 输入:nums = [2,7,11,15], target = 9 输出:[0,1] 解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。 示例 2: 输入:nums = [3,2,4], target = 6 阅读详情

Typescript 版算法实现


1 )方案一:参考最小堆类实现最大堆类及实现排序
class MaxHeap {
    heap: number[] = [];
    // 交换节点位置
    swap(i, j) {
        [this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]];
    }
    // 获得父节点
    getParentIndex(i) {
        return (i - 1) >> 1;
    }
    // 获取左子节点
    getLeftIndex(i) {
        return (i << 1) + 1; // 极客写法
    }
    // 获取右子节点
    getRightIndex(i) {
        return (i << 1) + 2;
    }
    // 向上移动
    shiftUp(index) {
        // 如果到了堆顶元素,index是0,则不要再上移了
        if(!index) return;
        const parentIndex = this.getParentIndex(index)
        if(this.heap[parentIndex] < this.heap[index]) {
            this.swap(parentIndex, index)
            this.shiftUp(parentIndex)
        }
    }
    // 下移
    shiftDown(index) {
        // 边界1:如果到了堆尾元素,则不要再下移了
        if(index >= this.heap.length - 1) return;
        const size = this.size();
        const leftIndex = this.getLeftIndex(index);
        const rightIndex = this.getRightIndex(index);
        if (leftIndex < size && this.heap[leftIndex] > this.heap[index]) {
            this.swap(leftIndex, index);
            this.shiftDown(leftIndex);
        }
        if (rightIndex < size && this.heap[rightIndex] > this.heap[index]) {
            this.swap(rightIndex, index);
            this.shiftDown(rightIndex);
        }
    }
    // 插入
    insert(value) {
        this.heap.push(value);
        this.shiftUp(this.heap.length - 1);
    }
    // 删除堆顶
    pop() {
        // pop()方法删除数组最后一个元素并返回,赋值给堆顶
        if (this.heap.length <= 1) return;
        this.heap[0] = this.heap.pop();
        // 对堆顶重新排序
        this.shiftDown(0);
    }
    // 获取堆顶
    peak() {
        return this.heap[0];
    }
    // 获取堆的大小
    size() {
        return this.heap.length;
    }
    sort(arr) {
    	// 1. 先构建一个最小堆
    	arr.forEach((n) => {
    		this.insert(n);
    	});
    	// 2. 开始依次排序,注意这个边界, pop不能是1,否则会造成死循环
    	const result = [];
    	while(this.heap.length > 1) {
    		result.push(this.peak());
    		this.pop();
    	}
    	// 3. 处理最后一个
    	result.push(this.peak());
    	this.heap = result;
    	return result;
    }
}

const mh = new MaxHeap();
mh.sort([1, 10, 9, 5, 3, 11, 3, 9, 11, 13, 1, -1, 98]);
console.log(mh.heap); // [98, 13, 11, 11, 10, 9, 9, 5, 3, 3, 1, 1, -1]

2 )方案二:另一种方式实现最大堆类及实现排序

class MaxHeap {
  heap: number[] = []
  // 交换两个元素
  static swap (arr, i, j) {
    if (i === j) return;
    [arr[i], arr[j]] = [arr[j], arr[i]];
  }
  // 构建最大堆的过程,递归
  static maxHeapify (Arr, i, size) {
    // 左节点(索引)
    const l = (i << 1) + 1
    // 右节点
    const r = (i << 1) + 2
    let largest = i;
    // 父节点i和左节点l做比较取最大
    if (l <= size && Arr[l] < Arr[largest]) largest = l;
    // 右节点和最大值比较
    if (r <= size && Arr[r] < Arr[largest]) largest = r;
    if (largest !== i) {
      MaxHeap.swap(Arr, i, largest);
      MaxHeap.maxHeapify(Arr, largest, size);
    }
  }
  sort () {
    const iArr = this.heap;
    const n = iArr.length;
    if (n <= 1) return iArr;
    // 这里,从最后一个父节点开始构建最大堆, 因为最后一个父节点到第一个父节点就是一次完整的构建最大堆的过程,完成后堆顶就是最大值
    for (let i = Math.floor(n / 2); i >= 0; i--) {
      MaxHeap.maxHeapify(iArr, i, n); // 这里最后一个参数 n 是完整的堆
    }
    // 减而治之
    for (let j = 0; j < n; j++) {
      MaxHeap.swap(iArr, 0, n - 1 - j); // 堆顶与最后一项互换, 堆顶被破坏, 堆顶变成最后一项
      MaxHeap.maxHeapify(iArr, 0, n - 1 - j - 1); // 这里逐渐缩小堆的规模,注意后面的减1,因为最后一个元素是排好序的最大值
    }
    return iArr
  }
}

const mh = new MaxHeap();
mh.heap = [1, 10, 9, 5, 3, 11, 3, 9, 11, 13, 1, -1, 98]
mh.sort();
console.log(mh.heap); // [98, 13, 11, 11, 10, 9, 9, 5, 3, 3, 1, 1, -1]
  • 这个排序的精髓是:在这个排序里先构建一次最大堆,获取排好序的最大值后,逐渐减而治之

Python3 版算法实现


1 ) 方案1

class MaxHeap:
    def __init__(self):
        self.heap = []

    # 交换节点位置
    def swap(self, i, j):
        self.heap[i], self.heap[j] = self.heap[j], self.heap[i]

    # 获得父节点
    def get_parent_index(self, i):
        return (i - 1) >> 1

    # 获取左子节点
    def get_left_index(self, i):
        return (i << 1) + 1

    # 获取右子节点
    def get_right_index(self, i):
        return (i << 1) + 2

    # 向上移动
    def shift_up(self, index):
        if index == 0:
            return
        parent_index = self.get_parent_index(index)
        if self.heap[parent_index] < self.heap[index]:
            self.swap(parent_index, index)
            self.shift_up(parent_index)

    # 下移
    def shift_down(self, index):
        if index >= len(self.heap) - 1:
            return
        size = self.size()
        left_index = self.get_left_index(index)
        right_index = self.get_right_index(index)
        if left_index < size and self.heap[left_index] > self.heap[index]:
            self.swap(left_index, index)
            self.shift_down(left_index)
        if right_index < size and self.heap[right_index] > self.heap[index]:
            self.swap(right_index, index)
            self.shift_down(right_index)

    # 插入
    def insert(self, value):
        self.heap.append(value)
        self.shift_up(len(self.heap) - 1)

    # 删除堆顶
    def pop(self):
        if len(self.heap) <= 1:
            return
        self.heap[0] = self.heap.pop()
        self.shift_down(0)

    # 获取堆顶
    def peak(self):
        return self.heap[0] if self.heap else None

    # 获取堆的大小
    def size(self):
        return len(self.heap)

    # 排序
    def sort(self, arr):
        for n in arr:
            self.insert(n)
        result = []
        while self.size() > 1:
            result.append(self.peak())
            self.pop()
        result.append(self.peak())
        self.heap = result
        return result

def main():
    mh = MaxHeap()
    sorted_array = mh.sort([1, 10, 9, 5, 3, 11, 3, 9, 11, 13, 1, -1, 98])
    print(sorted_array)  # 应该输出 [98, 13, 11, 11, 10, 9, 9, 5, 3, 3, 1, 1, -1]

if __name__ == "__main__":
    main()

2 )方案2

class MaxHeap:
    def __init__(self):
        self.heap = []

    # 交换两个元素
    @staticmethod
    def swap(arr, i, j):
        if i == j:
            return
        arr[i], arr[j] = arr[j], arr[i]

    # 构建最大堆的过程,递归
    @staticmethod
    def max_heapify(arr, i, size):
        l = (i << 1) + 1
        r = (i << 1) + 2
        largest = i
        if l <= size and arr[l] > arr[largest]:
            largest = l
        if r <= size and arr[r] > arr[largest]:
            largest = r
        if largest != i:
            MaxHeap.swap(arr, i, largest)
            MaxHeap.max_heapify(arr, largest, size)

    # 排序
    def sort(self):
        i_arr = self.heap
        n = len(i_arr)
        if n <= 1:
            return i_arr
        for i in range(n // 2, -1, -1):
            MaxHeap.max_heapify(i_arr, i, n - 1)
        for j in range(n):
            MaxHeap.swap(i_arr, 0, n - 1 - j)
            MaxHeap.max_heapify(i_arr, 0, n - 2 - j)
        return i_arr

def main():
    mh = MaxHeap()
    mh.heap = [1, 10, 9, 5, 3, 11, 3, 9, 11, 13, 1, -1, 98]
    sorted_array = mh.sort()
    print(sorted_array)  # 应该输出 [98, 13, 11, 11, 10, 9, 9, 5, 3, 3, 1, 1, -1]

if __name__ == "__main__":
    main()

Golang 版算法实现


1 ) 实现1

package main

import (
	"fmt"
)

type MaxHeap struct {
	heap []int
}

// 交换节点位置
func (h *MaxHeap) swap(i, j int) {
	h.heap[i], h.heap[j] = h.heap[j], h.heap[i]
}

// 获得父节点
func (h *MaxHeap) getParentIndex(i int) int {
	return (i - 1) >> 1
}

// 获取左子节点
func (h *MaxHeap) getLeftIndex(i int) int {
	return (i << 1) + 1
}

// 获取右子节点
func (h *MaxHeap) getRightIndex(i int) int {
	return (i << 1) + 2
}

// 向上移动
func (h *MaxHeap) shiftUp(index int) {
	if index == 0 {
		return
	}
	parentIndex := h.getParentIndex(index)
	if h.heap[parentIndex] < h.heap[index] {
		h.swap(parentIndex, index)
		h.shiftUp(parentIndex)
	}
}

// 下移
func (h *MaxHeap) shiftDown(index int) {
	if index >= len(h.heap)-1 {
		return
	}
	size := h.size()
	leftIndex := h.getLeftIndex(index)
	rightIndex := h.getRightIndex(index)
	if leftIndex < size && h.heap[leftIndex] > h.heap[index] {
		h.swap(leftIndex, index)
		h.shiftDown(leftIndex)
	}
	if rightIndex < size && h.heap[rightIndex] > h.heap[index] {
		h.swap(rightIndex, index)
		h.shiftDown(rightIndex)
	}
}

// 插入
func (h *MaxHeap) insert(value int) {
	h.heap = append(h.heap, value)
	h.shiftUp(len(h.heap) - 1)
}

// 删除堆顶
func (h *MaxHeap) pop() {
	if len(h.heap) <= 1 {
		return
	}
	h.heap[0] = h.heap[len(h.heap)-1]
	h.heap = h.heap[:len(h.heap)-1]
	h.shiftDown(0)
}

// 获取堆顶
func (h *MaxHeap) peak() *int {
	if len(h.heap) == 0 {
		return nil
	}
	return &h.heap[0]
}

// 获取堆的大小
func (h *MaxHeap) size() int {
	return len(h.heap)
}

// 排序
func (h *MaxHeap) sort(arr []int) []int {
	for _, n := range arr {
		h.insert(n)
	}
	result := make([]int, 0, len(arr))
	for h.size() > 1 {
		result = append(result, *h.peak())
		h.pop()
	}
	result = append(result, *h.peak())
	h.heap = result
	return result
}

func main() {
	mh := &MaxHeap{}
	sortedArray := mh.sort([]int{1, 10, 9, 5, 3, 11, 3, 9, 11, 13, 1, -1, 98})
	fmt.Println(sortedArray) // 应该输出 [98, 13, 11, 11, 10, 9, 9, 5, 3, 3, 1, 1, -1]
}

2 )实现2

package main

import (
	"fmt"
)

type MaxHeap struct {
	heap []int
}

// 交换两个元素
func (h *MaxHeap) swap(arr []int, i, j int) {
	if i == j {
		return
	}
	arr[i], arr[j] = arr[j], arr[i]
}

// 构建最大堆的过程,递归
func (h *MaxHeap) maxHeapify(arr []int, i, size int) {
	l := (i << 1) + 1
	r := (i << 1) + 2
	largest := i
	if l <= size && arr[l] > arr[largest] {
		largest = l
	}
	if r <= size && arr[r] > arr[largest] {
		largest = r
	}
	if largest != i {
		h.swap(arr, i, largest)
		h.maxHeapify(arr, largest, size)
	}
}

// 排序
func (h *MaxHeap) sort() []int {
	iArr := h.heap
	n := len(iArr)
	if n <= 1 {
		return iArr
	}
	for i := n / 2; i >= 0; i-- {
		h.maxHeapify(iArr, i, n-1)
	}
	for j := 0; j < n; j++ {
		h.swap(iArr, 0, n-1-j)
		h.maxHeapify(iArr, 0, n-2-j)
	}
	return iArr
}

func main() {
	mh := &MaxHeap{
		heap: []int{1, 10, 9, 5, 3, 11, 3, 9, 11, 13, 1, -1, 98},
	}
	sortedArray := mh.sort()
	fmt.Println(sortedArray) // 应该输出 [98, 13, 11, 11, 10, 9, 9, 5, 3, 3, 1, 1, -1]
}
使用podman 容器化安装DIFY 本文阐述了使用podman容器化安装DIFY的过程 阅读详情

相关推荐

画个板子玩一玩STM32F030F4P6,也许是最便宜的32bit MCU

前言,什么是STM32F030F4P6 STM32目前最便宜的芯片之一应该就是这一块,STM32F030F4P6,这一个芯片没有USB,但是其他都有,引脚少,价格低廉,如果找不到原厂,可以买替代的国产芯片,性能也一样。 不管怎么样也是Cortex-M0,比8bit和16bit的性能都强,总的来说就是低价,引脚少,体积小的同时,还容易开发,有很多模拟输入可玩,还有SPI,硬件I2C等等 所以,这一款MCU真的是从理论来说又便宜又好用,非常适合把玩。 画个板,最小系统 STM32F030其..

arenascat的博客 2万+

利用typescript实现堆排序

本文主要讲解堆排序的原理以及代码实现,要理解堆排序,首先需要了解二叉树,下面我们逐步展开树。

cswxb的博客 317

企业级AI Agent平台建设方案

本报告将深入剖析构成一个顶级AI Agent平台的各个功能层面,为构建者提供一份全面的战略蓝图。

分享AI和大数据领域的知识和研究 1588

TypeScript数据结构-大顶堆与小顶堆

熟悉数据结构的同学都知道,堆排序是一种利用堆数据结构而设计的算法,它的最好最差和平均时间复杂度都是O(nlogn),但同时它也是一种不稳的排序算法。本篇内容记录一下用TypeScript来实现堆排序的代码实现。 堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。这里我们用TS自带的数组来存储数据,在每次插入新数据时进行向下调整操作。而在弹出数据时,对顶部的数据进行下移操作,代码具...

hhdong123的专栏 424

2021年秋招面经分享·字节跳动【芯片工程师-系统架构】

前言 如果想参考本人背景情况的可见这篇概述 ============================ 正文开始 ============================== 【时间线】 7.29 字节一面 8.4 字节二面 8.11 字节三面 PS:红字表示我当时没答出来的问题,蓝字表示面试官的解答。 面经分享 一面·技术面【1小时5分钟】   面试官京腔重,聊high了所以没时间撕代码了,但是华为应该不会这样。 自我介绍; 介绍一下APB; APB中3个状态的跳转是怎么跳转的; AXI中va

qq_43132308的博客 5616

python基础:工作会用到的95%的基础python代码都在这了(万字详解!)

本文是一份Python编程语言的快速参考备忘单,涵盖了Python基础语法和常用数据类型。主要内容包括:Python入门指南(打印、变量声明)、内置数据类型(字符串、数值、列表、元组、集合、字典等)、控制结构(判断、循环)、函数定义、文件处理操作以及字符串操作方法(切片、循环遍历等)。这个备忘单特别适合初学者快速查阅Python基础语法,同时也提供了数据类型转换、f-string格式化字符串等实用技巧。通过简洁的代码示例展示了Python的基本语法规则和典型用法。

数据知道的博客 8164

数据结构与算法之堆: LeetCode 451. 根据字符出现频率排序 (Ts, Py, Go版)

1 )普通方法实现, 基于原生sort和Map结构。2 )使用堆排序

Wang的专栏 576

Qualcomm 常用NV列表

^ NV ITEM ^ 功能^^ |NV10 |mode prefer,找网模式|新平台使用NV80000| ^NV74 NV74=0关闭自动接听电话^ |NV240 |NV240=FALSE|EVDO出现网络的问题,此项必须设定为FALSE| |NV255 |CDMA规避网络列表(SID/NID号)| |NV256 |

sdrgtywretyeruet的专栏 5776

7种排序算法动画详解:从冒泡到堆排序的实战指南

排序算法是编程基础中的核心知识,也是面试和实际开发中频繁使用的技能。《Hello 算法》项目提供了动画图解、一键运行的数据结构与算法教程,支持 Java, C++, Python 等多种语言,帮助开发者直观理解排序算法的工作原理。本文将通过动画图解方式,详细解析7种常用排序算法的实现过程、优缺点及适用场景,让你轻松掌握排序算法的精髓。 ## 排序算法概览:选择最适合你的排序方案 🚀 排序算法

gitblog_00974的博客 531

Xilinx FPGA平台GTX简易使用教程(四)GTX IP核配置教程

干货来了,GTX IP核配置,搬砖全靠它~~

数字IC/FPGA杂货铺,找一找,或许有你想要的~ 1万+

使用 MATLAB/Simulink + Simscape Electrical 构建一个他励直流电机的启动与制动过程仿真模型

直流电机在工业控制、电动车辆、自动化设备中广泛应用。其中,他励直流电机(Separately Excited DC Motor)因其励磁绕组与电枢绕组分别供电,具有良好的调速性能和启动特性,常用于需要平稳启动和精确控制的场合。在实际应用中,电机的启动过程和制动过程对电网、机械系统以及电机本身都具有重要影响。因此,仿真分析他励直流电机的启动与制动特性,是电机控制设计的重要环节。本文将详细介绍如何使用构建一个他励直流电机的启动与制动过程仿真模型,并通过仿真分析其动态响应。本文详细介绍了如何使用构建一个。

amy_mhd的博客 233

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

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

Wang的专栏 4393

【JAVA】海康威视门禁机ISAPI接口开发,人脸上传更新接口

本文实现了一个HTTP工具类HTTPClientUtil,提供GET/POST/PUT/DELETE请求方法,支持摘要认证。工具类封装了Apache HttpClient,设置连接超时、最大连接数等参数,通过DeviceInfoDTO传递设备IP、端口和认证信息。文中还展示了两个应用示例:userInfoAdd()用于添加人员信息,FaceDataRecordAdd()用于添加人脸数据,均通过POST请求与设备ISAPI接口交互。该工具类简化了HTTP请求处理,支持设备管理系统的集成开发。

qq_27246521的博客 590

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

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

Wang的专栏 3374

OV9734 DATASHEET,完整规格书

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

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

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

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

Wang的专栏 3312

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

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

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

Wang的专栏 3119

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

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

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

Wang的专栏 2447

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

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

Wang的专栏 2270

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

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

Wang的专栏 2111

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

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

Wang的专栏 2103

数据结构与算法之堆: 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的专栏 1830

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

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

Wang的专栏 1793

数据结构与算法之动态规划: 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 23. 合并K个升序链表 (Ts, Py, Go版)
下一篇: 数据结构与算法之堆: LeetCode 451. 根据字符出现频率排序 (Ts, Py, Go版)
Wang's Blog
博客等级 码龄12年 7438粉丝 2421原创
评论
成就一亿技术人!
拼手气红包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、付费专栏及课程。

余额充值