【算法题】算法一本通

article/2025/8/12 17:21:29

每周更新至完结,建议关注收藏点赞。

目录

  • 待整理文章
  • 已整理的文章
  • 方法论
  • 数组与哈希表
  • 双指针(滑动窗口、二分查找、链表)
  • 前缀树
  • 堆 优先队列(区间/间隔问题、贪心 )
  • 回溯
  • 一维DP
  • 位操作
  • 数学与几何学
  • 二维DP
  • 随缘更新:高级图论

待整理文章

CodeCreek
[题单]
算法专栏

已整理的文章

以前发布的算法题文章都会汇总在这里,重新整理复习,优化内容,并注明出处。
本文所选题目均含有原题地址。以JS为主,补充其他语言代码。
算法题第一弹
算法题第二弹

部分代码借鉴灵神

方法论

超过10分钟就要看题解
按照专题分类,每专题做完进行总结->按分类拓扑图顺序从前往后->定期复习。
在这里插入图片描述

  • 由上面拓扑图可以得到顺序:
  1. 数组与哈希表
  2. 双指针(滑动窗口、二分查找、链表)
  3. 前缀树
  4. 堆 优先队列(区间/间隔问题、贪心 )
  5. 回溯
  6. 一维DP
  7. 位操作
  8. 数学与几何学
  9. 二维DP
  10. 随缘更新:高级图论

数组与哈希表

  1. 两数之和
    给定一个整数数组和一个目标值,找出数组中和为目标值的两个数的下标。
    用哈希表记录值和下标,在遍历过程中判断[目标值减当前值]是否已存在
    坑:先查再放,否则会匹配到自己
//js
var twoSum = function(nums, target) {const idx = new Map(); // 创建一个空哈希表for (let j = 0; ; j++) { // 枚举 jconst x = nums[j];// 在左边找 nums[i],满足 nums[i]+x=targetif (idx.has(target - x)) { // 找到了return [idx.get(target - x), j]; // 返回两个数的下标}idx.set(x, j); // 保存 nums[j] 和 j}
};
  1. 存在重复元素
//js
var containsDuplicate = function(nums) {return new Set(nums).size < nums.length;
};
  1. 有效的字母异位词
    用字符的ascii码作为下标,值为出现的次数,比对两个数组的值
//js
var isAnagram = function(s, t) {const cnt = Array(26).fill(0);for (const c of s) {cnt[c.charCodeAt(0) - 'a'.charCodeAt(0)]++;}for (const c of t) {cnt[c.charCodeAt(0) - 'a'.charCodeAt(0)]--;}return cnt.every(c => c === 0);
}//by the way:return _.isEqual(cntS, cntT);//深比较//_代表库别名,最常见的是 Lodash 或 Underscore.js库函数。
  1. 字母异位词分组
    字母异位词分组:就是把字母及数目相同,顺序不同的单词放到一组
    用排序后的字符串作为 key 分组,哈希表记录分组
    时间复杂度:O(n * k log k)
//js
var groupAnagrams = function(strs) {const m = new Map();for (const s of strs) {// 把 s 排序,作为哈希表的 keyconst sortedS = s.split('').sort().join('');if (!m.has(sortedS)) {m.set(sortedS, []);}// 排序后相同的字符串分到同一组m.get(sortedS).push(s);}// 哈希表的 value 保存分组后的结果return Array.from(m.values());
};
  1. 除自身以外数组的乘积
    构建两个数组,前缀乘积pre、后缀乘积post,答案就等于它们相乘。
    优化:要求O(1) 的额外空间复杂度,输出数组不被视为额外空间
    先计算post,后计算pre,把pre直接乘到post中,最后返回post,相当于post直接作为answer
    上述无论怎么优化,都至少需要两个先后的循环
  2. 前 K 个高频元素
    两种方法,堆、桶排序。
  3. 有效的数独
  4. 最长连续序列
  5. 整数反转
//js
Number.parseInt('123-')//好处在于它不会理会后面的非法字符,返回123var reverse = function(x) {    let re=x>=0 ? Number.parseInt(x.toString().split('').reverse().join('')) : Number.parseInt('-'+x.toString().split('').reverse().join(''))re=re<(-2)**31 || re>(2**31)-1 ? 0 : re    return re;
};
  1. 罗马整数
    本题的难点在于处理六种特殊规则,但可以统一成:
    设 x=s[i−1], y=s[i],这是两个相邻的罗马数字。
    如果 x 的数值小于 y 的数值,那么 x 的数值要取相反数。例如 IV 中的 I 相当于 −1。
    把所有数值相加,即为答案。
//js
const ROMAN = {'I': 1,'V': 5,'X': 10,'L': 50,'C': 100,'D': 500,'M': 1000,
};var romanToInt = function(s) {let ans = 0;for (let i = 1; i < s.length; i++) { // 遍历相邻的罗马数字const x = ROMAN[s[i - 1]], y = ROMAN[s[i]];ans += x < y ? -x : x;}return ans + ROMAN[s[s.length - 1]]; // 加上最后一个
};

  1. 括号匹配
//最简洁代码
var isValid = function(s) {    let origin=s;    while(s.length){s=origin.replace('()','').replace('[]','').replace('{}',''); if(s==origin)return false;        origin=s;    }    return true;
};

双指针(滑动窗口、二分查找、链表)

  1. 合并两个有序链表
    递归最简单
var mergeTwoLists = function(l1, l2) {    if (l1 === null) return l2;    else if (l2 === null) return l1;else if (l1.val < l2.val) {        l1.next = mergeTwoLists(l1.next, l2);        return l1;    } else {        l2.next = mergeTwoLists(l1, l2.next);        return l2;    }
};

前缀树

堆 优先队列(区间/间隔问题、贪心 )

回溯

  1. 数独游戏
    玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个同色九宫内的数字均含1-9,不重复。
    保证所有已知数据的格式都是合法的,并且题目有唯一的解。
    格式要求,输入9行,每行9个字符,0代表未知,其它数字为已知。
    输出9行,每行9个数字表示数独的解。例如:
    在这里插入图片描述
#include <stdio.h>
int a[9][9];int place(int x, int y) //二者分别是数组对应的行地址和列地址,取值为0-8
{int up, down, left, right;int i,j;up=x/3*3; //计算同色格子的范围down=up+3;left=y/3*3;right=left+3;//以下分三种情况判断是否在x,y对应的位置放这个数,如果不可以放,返回0,如果可以放,返回1,会进一步迭代for(i=0;i<9;i++){if(a[x][y]==a[i][y] && i!=x && a[i][y]!=0)return 0;		}for(i=0;i<9;i++){if (a[x][y]==a[x][i] && i!=y && a[x][i]!=0)return 0;		}for(i=up;i<down;i++)//同色9宫格的情况{for(j=left;j<right;j++)if(i!=x || j!=y)//不是自己即可{if(a[i][j]==a[x][y] && a[i][j]!=0)return 0;}}return 1;	
}void backtrack(int t)//第几个格子
{int i,j;int x,y;if(t==81){for(i=0;i<9;i++){for(j=0;j<9;j++)printf("%d",a[i][j]);		putchar('\n');}}else{x=t/9;y=t%9; //将这个转换为相应的数组行坐标和列坐标if(a[x][y]!=0)backtrack(t+1);else{for(i=1;i<10;i++){a[x][y]=i;if(place(x,y)==1)backtrack(t+1);a[x][y]=0;//回溯操作}}}
}int main()
{char str[9][9];int i,j;for(i=0;i<9;i++)gets(str[i]);for(i=0;i<9;i++)for(j=0;j<9;j++)a[i][j]=str[i][j]-'0';backtrack(0);return 0;
}
  1. 今有7对数字:两个1,两个2,两个3,…两个7,把它们排成一行。
    要求,两个1间有1个其它数字,两个2间有2个其它数字,以此类推,两个7之间有7个其它数字。
    如下就是一个符合要求的排列:17126425374635当然,如果把它倒过来,也是符合要求的。
    请你找出另一种符合要求的排列法,并且这个排列法是以74开头的。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<stdlib.h>
#include<algorithm>
#include<cmath>
using namespace std;
int arr[16]={0};
int dfs(int n)
{if(n > 6) return 1;//因为7已经确定,所以最大放入数就是6if(n == 4) n++;//4的位置已经确定,所以跳过int i = 0;for(i = 3;i <=14 ;i++){if(i == 7 || i == 9) continue;//7,9位置值已经定了if(i+n+1 <=14 && arr[i]==0 &&arr[i+n+1]==0)//保证两个位置都没有数据{arr[i] = arr[i+n+1] = n;if(dfs(n+1))//改变数字return 1;arr[i] = arr[i+n+1] = 0;//回溯回来证明不符合条件,恢复上一次dfs状态}}return 0;
}
int main()
{arr[1] = 7,arr[2] = 4;//因为题目上已经给出两个开头,可以推出后面两个arr[9] = 7,arr[7] = 4;dfs(1);//放入数字1for(int i = 1;i < 16;i++ ){cout <<arr[i];}cout <<"\n";return 0;
}

一维DP

位操作

  1. 整数反转
    在这里插入图片描述
/*** @param {number} x* @return {number}*/
var reverse = function(x) {let result = 0;while(x !== 0) {result = result * 10 + x % 10;x = (x / 10) | 0;//通过 | 0 取整,无论正负,只移除小数点部分(正数向下取整,负数向上取整)。}return (result | 0) === result ? result : 0;//|只能处理32位内的,所以可以用来判断是否溢出32位
};
  • 为啥通过 | 0 取整,无论正负,只移除小数点部分(正数向下取整,负数向上取整)?
    在 JavaScript 中,当你对一个数字执行位运算符(如 |、&、^、~、<<、>>、>>>)时,JavaScript 引擎会执行以下步骤:
    将操作数转换为 32 位带符号整数。(故局限性也是只能处理32位带符号整数范围内)
    当一个浮点数被转换为 32 位整数时,它的小数部分会被直接截断(丢弃)。
    x | 0得到x本身,所以说这个操作只是去除小数部分。

数学与几何学

  1. x的x次幂结果为10,计算出x的近似值,这个值是介于2和3之间的一个数字。x的值计算到小数后6位(四舍五入)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<stdlib.h>
#include<algorithm>
#include<cmath>
using namespace std;int main()
{double a=2.0;for(;a<3;a+=0.0000001)//要比要求的6位小数多出一位才能四舍五入{if(fabs(pow(a,a)-10.0)<0.000001)break;}printf("%6lf",a); //lf是double格式 return 0;
}
  1. 大数勾股定理
    已知直角三角形的斜边是某个整数,并且要求另外两条边也必须是整数。求满足这个条件的不同直角三角形的个数。
    输入一个整数 n (0<n<10000000) 表示直角三角形斜边的长度。要求输出一个整数,表示满足条件的直角三角形个数。
    资源约定:
    峰值内存消耗 < 256M
    CPU消耗 < 1000ms
#include<stdio.h>
#include<math.h>
int main()
{long long n,i,j,sum=0,m;//~按位取反//使得当 scanf 读取失败时 返回EOF (-1)//-1 是 32 位整数 1...1111 (所有位都是 1) 则循环终止while(~scanf("%lld",&n)){for(i=1;i<n;i++){j=sqrt(n*n-i*i);if(j*j==n*n-i*i)sum++;}printf("%lld\n",sum/2);}return 0;}
  1. 埃及分数
    形如:1/a 的分数称为单位分数。可以把1分解为若干个互不相同的单位分数之和。
    例如:
    1 = 1/2 + 1/3 + 1/9 + 1/18
    1 = 1/2 + 1/3 + 1/10 + 1/15
    1 = 1/3 + 1/5 + 1/7 + 1/9 + 1/11 + 1/15 + 1/35 + 1/45 + 1/231
    等等,类似这样的分解无穷无尽。
    我们增加一个约束条件:最大的分母必须不超过30
    请你求出分解为n项时的所有不同分解法。
    数据格式要求:
    输入一个整数n,表示要分解为n项(n<12)
    输出分解后的单位分数项,中间用一个空格分开。
    每种分解法占用一行,行间的顺序按照分母从小到大排序。
    例如,
    输入:
    4
    程序应该输出:
    1/2 1/3 1/8 1/24
    1/2 1/3 1/9 1/18
    1/2 1/3 1/10 1/15
    1/2 1/4 1/5 1/20
    1/2 1/4 1/6 1/12
    再例如,
    输入:
    5
    程序应该输出:
    1/2 1/3 1/12 1/21 1/28
    1/2 1/4 1/6 1/21 1/28
    1/2 1/4 1/7 1/14 1/28
    1/2 1/4 1/8 1/12 1/24
    1/2 1/4 1/9 1/12 1/18
    1/2 1/4 1/10 1/12 1/15
    1/2 1/5 1/6 1/12 1/20
    1/3 1/4 1/5 1/6 1/20
    资源约定:
    峰值内存消耗 < 256M
    CPU消耗 < 2000ms

先研究一下数学原理 1=30/30
这个分母就是30,分子也是30,将分子的30做分解就可以了。列出1-29之内相加等于30的各种可能,然后将这些数和分母约分就可以了
比如:30=2+3+25
则1=(2+3+25)/30
1=1/15+1/10+5/6
加了限制项n 时,就更加好办了,就是求n个数相加等于30
等式可以认为是(a1+a2+…am)/K,很好理解,a1,…am必然是K的所有约数的和的组合。因此最后题目就是转化为求一个数K的所有约数(质因子),题目K最大才30,之后求出所有约数中,n个数的和等于K的组合。
比如:K=30,30=235,根据“约数个数定理”,约数有8个,除去自己本身和1就剩6个,为2,3,5,6,10,15,
如果你输入n=4,那么就是求这6个约数中,哪4个相加正好等于30的所有组合,根据组合原理,C(7,4)才210中组合,因此循环不会很久。
题目没规定K值,因此,需要K从1到30循环,对每一次循环的K,找出所有所有约数,并对所有约数个数不小于n的情况,循环找出所有n个约数等于K的组合。
建议搜索:
1、约数个数定理
2、求求一个数的所有约数(或者质因子)
3、从N个数中任选M个数相加的和等于K(循环应该就能解决)

二维DP

随缘更新:高级图论


http://www.hkcw.cn/article/AAELgwmySK.shtml

相关文章

Spring如何实现组件扫描与@Component注解原理

Spring如何实现组件扫描与Component注解原理 注解配置与包扫描的实现机制一、概述&#xff1a;什么是注解配置与包扫描&#xff1f;二、处理流程概览三、注解定义ComponentScope 四、核心代码结构1. ClassPathScanningCandidateComponentProvider2. ClassPathBeanDefinitionSca…

NLP学习路线图(十六):N-gram模型

一、为何需要语言模型&#xff1f;概率视角下的语言本质 自然语言处理的核心挑战在于让机器“理解”人类语言。这种理解的一个关键方面是处理语言的歧义性、创造性和结构性。语言模型&#xff08;Language Model, LM&#xff09;为此提供了一种强大的数学框架&#xff1a;它赋…

使用ReactNative加载HarmonyOS Svga动画

这是一款使用ReactNative 加载HarmonyOS Svga动画的播放器插件 三端Svga动画统一使用点击这里 版本:v1.1.2 react-native-ohos-svgaplayer [!TIP] Github 地址 安装与使用 npm npm install react-native-ohos-svgaplayer yarn yarn add react-native-ohos-svgaplayer下面…

电路图识图基础知识-高、低压供配电系统一次系统识图(十一)

1、高、低压供配电 一 次系统的介绍 供配电系统中输送、分配和使用电能的电路&#xff0c;称为一次电路或一次回路&#xff0c;也称为一次系统或主接线。控制、指示、测量和保护一次电路及其中设备运行的电路&#xff0c;称为二次电路或二次回路.也称为二次系统。 工厂供配电系…

read-bridge开源程序是AI 增强阅读工具,使用 n+1 方法进行沉浸式语言学习。通过留在目标语言生态系统中学习语言,具有以流状态为中心的界面。

​一、软件介绍 文末提供程序和源码下载 read-bridge开源程序是AI 增强阅读工具&#xff0c;使用 n1 方法进行沉浸式语言学习。通过留在目标语言生态系统中学习语言&#xff0c;具有以流状态为中心的界面。 二、Overview 概述 此阅读助手支持源到源语言学习方法&#xff0c;减…

调教 DeepSeek - 输出精致的 HTML MARKDOWN

【序言】 不知道是不是我闲的蛋疼&#xff0c;对百度AI 和 DeepSeek 的回答都不太满意。 DeepSeek 回答句子的引用链接&#xff0c;始终无法准确定位。有时链接只是一个域名&#xff0c;有时它给的链接是搜索串如: baidu.com/?q"搜索内容"。 百度AI 回答句子的引用…

【论文阅读 | PR 2024 |ICAFusion:迭代交叉注意力引导的多光谱目标检测特征融合】

论文阅读 | PR 2024 |ICAFusion&#xff1a;迭代交叉注意力引导的多光谱目标检测特征融合 1.摘要&&引言2.方法2.1 架构2.2 双模态特征融合&#xff08;DMFF&#xff09;2.2.1 跨模态特征增强&#xff08;CFE&#xff09;2.2.2 空间特征压缩&#xff08;SFS&#xff09;…

本振相参解析(1)2025.6.1

前言 本振相参是射频与通信系统中的关键技术概念&#xff0c;涉及本机振荡器&#xff08;LO&#xff09;信号的相位稳定性和多信号间的相干性控制。以下从定义、关键技术、应用场景及挑战等方面展开分析&#xff1a; 一、核心概念解析 本振&#xff08;Local Oscillator, LO…

一个完整的日志收集方案:Elasticsearch + Logstash + Kibana+Filebeat (一)

整体链路 [应用服务器] --> [Filebeat] --> [Logstash] --> [Elasticsearch] --> [Kibana] 组件职责 Kibana&#xff1a; 可视化和分析日志数据Elasticsearch&#xff1a; 存储和索引日志数据Logstash&#xff1a; 解析、转换和丰富日志数据Filebeat&#xff1a…

Notepad++找回自动暂存的文件

场景&#xff1a; 当你没有保存就退出Notepad&#xff0c;下次进来Notepad会自动把你上次编辑的内容显示出来&#xff0c;以便你继续编辑。除非你手动关掉当前页面&#xff0c;这样Notepad就会删除掉自动保存的内容。 问题&#xff1a; Notepad会将自动保存的文件地址,打开Note…

VMware-VMRC-12.0.1-18113358安装包下载安装与使用(附下载)

文章目录 简介1、下载地址2、安装使用总结 简介 VMware-VMRC&#xff08;VMware Virtual Machine Remote Console&#xff09; 是 VMware 提供的一款远程控制台工具&#xff0c;用于连接和管理 VMware 虚拟化环境中的虚拟机&#xff08;VM&#xff09;。它允许用户通过图形界面…

车载诊断框架 ---CAN诊断多帧传输时间参数记忆口诀

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…

docker、ctr、crictl命令简介与使用

概述 在使用k3s过程中&#xff0c;经常需要使用ctr和crictl两个命令&#xff0c;本文记录一下。 ctr 类似docker命令是docker-shim容器运行时的客户端工具&#xff0c;ctr是Containerd的客户端工具。一个简单的CLI接口&#xff0c;用作Containerd本身的一些调试用途&#xf…

Docker安装mitproxy

一&#xff1a;概述 mitmproxy 是一组工具&#xff0c;可为 HTTP/1、HTTP/2 和 WebSockets 提供支持 SSL/TLS 的交互式拦截代理。 二&#xff1a;安装 2.1 运行并拉取镜像 ocker run --rm -it -p 8080:8080 -p 0.0.0.0:8081:8081 mitmproxy/mitmproxy mitmweb --web-host 0.0…

Linux 简单模拟实现C语言文件流

&#x1f307;前言 在 C语言 的文件流中&#xff0c;存在一个 FILE 结构体类型&#xff0c;其中包含了文件的诸多读写信息以及重要的文件描述符 fd&#xff0c;在此类型之上&#xff0c;诞生了 C语言 文件相关操作&#xff0c;如 fopen、fclose、fwrite 等&#xff0c;这些函数…

数据要素×AI:高质量数据集如何成为智能时代的“新石油“

在数字中国建设峰会上&#xff0c;国家数据局提出的"三类高质量数据集"建设规划引发广泛关注。这不仅是技术层面的创新&#xff0c;更是对数据要素价值释放路径的深刻思考。当我们站在AI产业化的关键节点回望&#xff0c;会发现数据正在经历一场从"原料"到…

CCPC dongbei 2025 I

题目链接&#xff1a;https://codeforces.com/gym/105924 题目背景&#xff1a; 给定一个二分图&#xff0c;左图编号 1 ~ n&#xff0c;右图 n 1 ~ 2n&#xff0c;左图的每个城市都会与右图的某个城市犯冲&#xff08;每个城市都只与一个城市犯冲&#xff09;&#xff0c;除…

如何学习开关电源?从“大”到“小”学习开关电源...

01 / 简介 / 参考 开关电源研学群[BUCK] ,之前创建了开关电源研学群,为电源同行提供学习交流的平台。参考 一种高效的硬件工程师学习方法[更新篇,更牛逼,加量不加价] ,之前也给大家推荐了更加高效的学习方法。 群内有很多电源大佬,经常给大家解答疑问,在此表示感谢;…

C#里与嵌入式系统W5500网络通讯(3)

有与W5500通讯时,需要使用下面的寄存器: PHYCFGR (W5500 PHY Configuration Register) [R/W] [0x002E] [0b10111XXX] PHYCFGR configures PHY operation mode and resets PHY. In addition, PHYCFGR indicates the status of PHY such as duplex, Speed, Link. 这张表格详细…

WEB3——开发者怎么查看自己的合约日志记录

在区块链中查看合约的日志信息&#xff08;也叫事件 logs&#xff09;&#xff0c;主要有以下几种方式&#xff0c;具体方法依赖于你使用的区块链平台&#xff08;如 Ethereum、BSC、Polygon 等&#xff09;和工具&#xff08;如 Etherscan、web3.js、ethers.js、Hardhat 等&am…