71题跳过(这是CSP那个目录吗....)
72. 编辑距离
难度困难1136
给你两个单词 word1 和 word2,请你计算出将 word1 转换成 word2 所使用的最少操作数 。
你可以对一个单词进行如下三种操作:
示例 1:
输入:word1 = "horse", word2 = "ros" 输出:3 解释: horse -> rorse (将 'h' 替换为 'r') rorse -> rose (删除 'r') rose -> ros (删除 'e')
示例 2:
输入:word1 = "intention", word2 = "execution" 输出:5 解释: intention -> inention (删除 't') inention -> enention (将 'i' 替换为 'e') enention -> exention (将 'n' 替换为 'x') exention -> exection (将 'n' 替换为 'c') exection -> execution (插入 'u')
先用递归来一个
再用动规来一个
因为不知道哪个次数最少,所以都拉来一遍看min
递归:
unordered_map,int> mp;
这样就用,嘤嘤嘤。。。。
int get(int i,int j,string word1,string word2){
pair p(i,j);
if(i==-1) mp[p]=j+1;
if(j==-1) mp[p]=i+1;
if(word1[i]==word2[j]){
if(!mp.count(p))
mp[p]=get(i-1,j-1,word1,word2);
}else{
if(!mp.count(p))
mp[p]=
min(get(i-1,j-1,word1,word2)+1,min(
get(i-1,j,word1,word2)+1,
get(i,j-1,word1,word2)+1
));
}
return mp[p];
}
重叠子问题
自底而上的思考。
int minDistance(string word1, string word2) {
// int i=word1.size()-1;
// int j=word2.size()-1;
// return get(i,j,word1,word2);
//但是base是-1 !!
int n=word1.size();
int m=word2.size();
vector> dp(n+1,vector(m+1,0));
for(int i=0;i<=n;i++) dp[i][0]=i;
for(int j=0;j<=m;j++) dp[0][j]=j;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(word1[i-1]==word2[j-1])
dp[i][j]=dp[i-1][j-1];
else
dp[i][j]=min(dp[i-1][j-1]+1,
min(dp[i-1][j]+1,dp[i][j-1]+1));
}
}
return dp[n][m];
}
73. 矩阵置零
难度中等290
给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。请使用原地算法。
示例 1:
输入: [ [1,1,1], [1,0,1], [1,1,1] ] 输出: [ [1,0,1], [0,0,0], [1,0,1] ]
示例 2:
输入: [ [0,1,2,0], [3,4,5,2], [1,3,1,5] ] 输出: [ [0,0,0,0], [0,4,5,0], [0,3,1,0] ]
进阶:
class Solution {
public:
void setZeroes(vector>& matrix) {
set col,row;
for(int i=0;i
public void setZeroes(int[][] matrix) {
if(matrix == null || matrix.length == 0)
return;
int m = matrix.length, n = matrix[0].length;
boolean firstRow = false, firstCol = false;
//步骤一
for(int i = 0; i < m; i++){
if(matrix[i][0] == 0)
firstCol = true;
}
for(int j = 0; j < n; j++){
if(matrix[0][j] == 0)
firstRow = true;
}
//步骤二
for(int i = 1; i < m; i++){
for(int j = 1; j < n; j++){
if(matrix[i][j] == 0){
matrix[i][0] = 0;
matrix[0][j] = 0;
}
}
}
//步骤三
for(int i = 1; i < m; i++){
if(matrix[i][0] == 0){
for(int j = 0; j < n; j++)
matrix[i][j] = 0;
}
}
for(int j = 1; j < n; j++){
if(matrix[0][j] == 0){
for(int i = 0; i < m; i++)
matrix[i][j] = 0;
}
}
//步骤四
if(firstRow){
for(int j = 0; j < n; j++)
matrix[0][j] = 0;
}
if(firstCol){
for(int i = 0; i < m; i++)
matrix[i][0] = 0;
}
}
作者:lan-se-bei-ban-qiu
链接:https://leetcode-cn.com/problems/set-matrix-zeroes/solution/ju-zhen-zhi-0de-liang-chong-fang-fa-by-lan-se-bei-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
74. 搜索二维矩阵
难度中等239
编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:
示例 1:
输入: matrix = [ [1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50] ] target = 3 输出: true
示例 2:
输入: matrix = [ [1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50] ] target = 13 输出: false
class Solution {
public:
bool searchMatrix(vector>& matrix, int target) {
int m=matrix.size();
if(m==0) return false;
int n=matrix[0].size();
int x=m-1;int y=0;
while(x>=0&&x=0&&y
75. 颜色分类
难度中等578
给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
注意:
不能使用代码库中的排序函数来解决这道题。
示例:
输入: [2,0,2,1,1,0] 输出: [0,0,1,1,2,2]
进阶:
解法很聪明哦
做对这道题需要熟悉快速排序的 partition 过程。
partition 过程经过一次扫描把整个数组分成三个部分,正好符合这个问题的场景。
写对这道题的方法是,把我们对循环不变量的定义作为注释先写出来,然后再编码。
作者:liweiwei1419
链接:https://leetcode-cn.com/problems/sort-colors/solution/kuai-su-pai-xu-partition-guo-cheng-she-ji-xun-huan/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
public:
void sortColors(vector& nums) {
int l=0, r=nums.size()-1;
int cur=0;
while(cur<=r){
if(nums[cur]==0){
swap(nums[cur],nums[l]);l++;cur++;
}else if(nums[cur]==2){
swap(nums[cur],nums[r]);r--;
}else cur++;
}
return;
}
};
76. 最小覆盖子串
难度困难745
给你一个字符串 S、一个字符串 T 。请你设计一种算法,可以在 O(n) 的时间复杂度内,从字符串 S 里面找出:包含 T 所有字符的最小子串。
示例:
输入:S = "ADOBECODEBANC", T = "ABC" 输出:"BANC"
提示:
""
。滑动窗口的关键是什么!!!
string minWindow(string s, string t) {
//滑动窗口还用说吗...
unordered_map need,window;
for(char i:t) need[i]++;
int valid=0;//是否包含
int left=0,right=0;
int st,len=INT_MAX;
while(right
77. 组合
难度中等394
给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。
示例:
输入: n = 4, k = 2 输出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]
class Solution {
public:
void get(vector& temp,int num,int k,vector> &ans,int index,int n){
if(num==k){
ans.push_back(temp);return;
}
if(index==n+1||num>k) return;
temp.push_back(index);
get(temp,num+1,k,ans,index+1,n);
temp.pop_back();
get(temp,num,k,ans,index+1,n);
}
vector> combine(int n, int k) {
vector> ans;
if(n==0||k==0) return ans;
vector temp;
get(temp,0,k,ans,1,n);
return ans;
}
};
78. 子集
难度中等749
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
示例:
输入: nums = [1,2,3] 输出: [ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ]
class Solution {
public:
vector tmp;
void get(int xuan,int sum,int n,vector> &ans,vector& nums){
if(sum==n){
// if(xuan==0) return;
ans.push_back(tmp);return;
}
get(xuan,sum+1,n,ans,nums);
tmp.push_back(nums[sum]);
get(xuan+1,sum+1,n,ans,nums);
tmp.pop_back();
}
vector> subsets(vector& nums) {
vector> ans;
// ans.push_back({});
//每一个元素,选或者不选~
get(0,0,nums.size(),ans,nums);
return ans;
}
};
79. 单词搜索
难度中等611
给定一个二维网格和一个单词,找出该单词是否存在于网格中。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
示例:
board = [ ['A','B','C','E'], ['S','F','C','S'], ['A','D','E','E'] ] 给定 word = "ABCCED", 返回 true 给定 word = "SEE", 返回 true 给定 word = "ABCB", 返回 false
提示:
board
和 word
中只包含大写和小写英文字母。1 <= board.length <= 200
1 <= board[i].length <= 200
1 <= word.length <= 10^3
class Solution {
public:
int t[4][2]={
{0,1},{0,-1},{1,0},{-1,0}};
bool ans=false;
void get(vector>& board,vector>& visit,int index,string word,int x,int y,int n,int m){
if(ans) return;
if(index==word.size()-1&&board[x][y]==word[index]){
ans= true;return;
}
if(board[x][y]==word[index]){
visit[x][y]=true;
for(int i=0;i<4;i++){
int tx=x+t[i][0];
int ty=y+t[i][1];
if(tx<0||ty<0||tx>=n||ty>=m||visit[tx][ty]==true) continue;
get(board,visit,index+1,word,tx,ty,n,m);
}
visit[x][y]=false;
}
}
bool exist(vector>& board, string word) {
//这就是简单的dfs吧..
int n=board.size();
int m=board[0].size();
vector> visit(n,vector(m,false));
for(int i=0;i
80. 删除排序数组中的重复项 II
难度中等285
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
示例 1:
给定 nums = [1,1,1,2,2,3], 函数应返回新长度 length =5
, 并且原数组的前五个元素被修改为1, 1, 2, 2,
3 。 你不需要考虑数组中超出新长度后面的元素。
示例 2:
给定 nums = [0,0,1,1,1,1,2,3,3], 函数应返回新长度 length =7
, 并且原数组的前五个元素被修改为0
, 0, 1, 1, 2, 3, 3 。 你不需要考虑数组中超出新长度后面的元素。
//这个我不会!!!!我的天
看了下有条件没应用啊,这个nums[index-k+1] 怪不得
class Solution {
public int removeDuplicates(int[] nums) {
int i = 0;
for (int n : nums) {
if (i < 2 || n > nums[i-2]) nums[i++] = n;
}
return i;
}
}