2021.4.10+11学习随笔_lc_每日一题
作者:互联网
学习随笔
丑数①和②
- 暴力法+三指针法
丑数①
给你一个整数 n ,请你判断 n 是否为 丑数 。如果是,返回 true ;否则,返回 false 。
丑数 就是只包含质因数 2、3 和/或 5 的正整数。
具体代码
bool isUgly(int n) {
if (n <= 0) return false;
while (n % 2 == 0) n = n / 2;
//!? 去除n中所有为2的因子
while (n % 3 == 0) n = n / 3;
//!? 去除n中所有为3的因子
while (n % 5 == 0) n = n / 5;
//!? 去除n中所有为3的因子
if (n == 1)return true;
return false;
}
丑数②
给你一个整数 n ,请你找出并返回第 n 个 丑数 。
丑数 就是只包含质因数 2、3 和/或 5 的正整数。
具体代码
int nthUglyNumber(int n) {
vector<int> v(n + 5);
int idx2 = 1, idx3 = 1, idx5 = 1;
v[1] = 1;
for (int i = 2; i <= n; i++)
{
v[i] = min(v[idx2] * 2, min(v[idx3] * 3, v[idx5] * 5));
//!? min 和三指针idx 让v[i]的值都是单调递增的,
if (v[i] == v[idx2] * 2) idx2++;
if (v[i] == v[idx3] * 3) idx3++;
if (v[i] == v[idx5] * 5) idx5++;
//!? 这里最巧妙的是三个if操作,这里的if是起到两个作用
//!? 一、如果v[idx2]的值被用到,那么移动idx2;
//!? 二、起到去重操作,如果这个数同样符合下面的两个if,那么同样会跳过该idx3,idx5,跳过该数
}
return v[n];
}
最长公共子序列
- 动态规划
- 最长公共子序列问题
最长公共子序列
给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。
一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。
例如,“ace” 是 “abcde” 的子序列,但 “aec” 不是 “abcde” 的子序列。
两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列。
具体代码
int longestCommonSubsequence(string text1, string text2) {
int n=text1.size(),m=text2.size();
int a[n+1][m+1];
memset(a, 0, sizeof(a));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(text1[i-1]==text2[j-1])
{
a[i][j]=a[i-1][j-1]+1;
}
else
{
a[i][j]=max(a[i-1][j],a[i][j-1]);
}
}
}
return a[n][m];
}
直方图的雨量
- 双指针
直方图的雨量
给定一个直方图(也称柱状图),假设有人从上面源源不断地倒水,最后直方图能存多少水量?直方图的宽度为 1
具体代码
int trap(vector<int>& height) {
int sum = accumulate(height.begin(), height.end(), 0);//已有的格子的数量
int l = 0, r = height.size() - 1;//不同层的边界点
int h = 1, volume = 0;
while (l <= r)
{
while (l <= r&&height[l] < h)
{
l++;
}
while (l <= r&&height[r] < h)
{
r--;
}
volume += r - l + 1;
h++;
}
return volume - sum;
}
学习产出:
- 学习了三指针法
- 复习了最长公共子序列
- 巧妙运用双指针解决问题
标签:11,10,2021.4,丑数,int,字符串,直方图,序列,idx2 来源: https://blog.csdn.net/qq_40591773/article/details/115604418