很久没刷算法题了,看到题后虽然有印象,但对于边界范围的判断很是吃力,多次提交才通过。记录一下方便后续回顾。
数组中的第K个最大元素(leetcode215)
c++代码:
#include <iostream>
#include <vector>
using namespace std;
// 数组中的第K个最大元素
/**
* 算法思路: 使用插入排序获取到partiton等于length-k的数组值
*
*/
class Solution {
public:
int findKthLargest(vector<int> &nums, int k) {
int start = 0, end = nums.size() - 1;
int target = nums.size() - k;
while (true) {
int p = partition(nums, start, end);
if (p == target) {
return nums[p];
} else if (p < target) {
start = p + 1;
} else {
end = p - 1;
}
}
}
private:
int partition(vector<int> &arr, int left, int right) {
int pivot = arr[right];
while (left < right) {
while (left < right && arr[left] < pivot) {
left++;
}
if (left < right) {
swap(arr[left], arr[right]);
right--;
}
while (left < right && arr[right] > pivot) {
right--;
}
if (left < right) {
swap(arr[left], arr[right]);
left++;
}
}
swap(arr[left], pivot);
return left;
}
void swap(int &a, int &b) {
int temp = a;
a = b;
b = temp;
}
};
int main() {
vector<int> arr = {3, 2, 3, 1, 2, 4, 5, 5, 6};
int k = 4;
Solution S;
int result = S.findKthLargest(arr, k);
cout << "结果为:" << result << endl;
return 0;
}
调库取巧:
c++:
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
sort(nums.begin(),nums.end());
return nums[nums.size()-k];
}
};
python:
from typing import List
class Solution:
def findKthLargest(self, nums: List[int], k: int) -> int:
# return sorted(nums)[-k] # 对新的列表操作
nums.sort()
return nums[-k] # 对nums原地操作
if __name__ == '__main__':
nums = [3, 2, 3, 1, 2, 4, 5, 5, 6]
k = 4
s = Solution()
result = s.findKthLargest(nums, k)
print(result)
调库真的很丝滑,比自己写的运行快。
无重复字符的最长字串(leetcode3)
C++
#include <iostream>
#include <string>
using namespace std;
class Solution {
public:
int lengthOfLongestSubstring(string s) {
// 为空则返回长度为0
if (s.empty()){
return 0;
}
// 初始一个滑动窗口的首位指针。
int start = 0, end = 1;
int result_start = 0, result_end = 1; // 记录结果字符串的首尾位置
// 开始遍历字符串
while(end<s.length()){
for(int i=start;i<end;i++){ // 遍历是否有重复
if(s[end] == s[i]){ // 出现重复,则更新起始指针
if((end-start)>(result_end-result_start)){ // 出现更大值则更新
result_end = end;
result_start = start;
}
start = i+1; // 将窗口起始指针置于重复位置的下一个位置
break;
}
}
end++;
}
if((end-start)>(result_end-result_start)){ // 出现更大值
result_end = end;
result_start = start;
}
/*** 可视化结果输出
string result;
for(int i=result_start;i<result_end;i++){
result+=s[i];
}
cout<< result<<endl;
*/
return result_end-result_start;
}
};
// 测试函数
int main() {
string nums = "pwwkew";
Solution solution;
int result = solution.lengthOfLongestSubstring(nums);
cout << result << endl;
return 0;
}
Python
# 无重复字符的最长字串
class Solution:
def lengthOfLongestSubstring(self, s):
if not s:
return 0
start = 0 # 滑动窗口起始指针
end = 1 # 滑动窗口结束指针
result = s[start] # 初始无重复子字符串
while end<len(s): # 滑动
if s[end] in s[start:end]: # 出现重复
if (end-start)>len(result): # 比已知结果子字符串更长则更新结果子串
result= s[start:end]
while s[start] != s[end]: # 将起始指针滑动到重复位置
start+=1
start+=1 # 将起始指针滑动到重复位置的下一个位置
end+=1 # 结束指针向末尾滑动
if (end - start) > len(result): # 滑动结束后,如果窗口子串比已知结果子字符串更长则更新结果子串
result = s[start:end]
return len(result) # 返回最长子字符串长度
if __name__ == '__main__':
s = 'abcabcbb'
p = Solution()
res = p.lengthOfLongestSubstring(s)
print(res)
编辑距离(leetcode72)
c++
#include <vector>
#include <iostream>
#include <string>
using namespace std;
class Solution {
public:
int minDistance(string word1, string word2) {
if (word1.empty()) {
return word2.size();
}
if (word2.empty()) {
return word1.size();
}
vector<vector<int>> dp(word1.size() + 1, vector<int>(word2.size() + 1));
for (int i = 0; i < word1.size() + 1; i++) {
dp[i][0] = i;
}
for (int i = 0; i < word2.size() + 1; i++) {
dp[0][i] = i;
}
for (int i = 1; i < word1.size() + 1; i++) {
for (int j = 1; j < word2.size() + 1; j++) {
if (word1[i - 1] == word2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1];
} else {
dp[i][j] = min(dp[i][j - 1], min(dp[i - 1][j - 1], dp[i - 1][j]))+1;
}
}
}
return dp[word1.size()][word2.size()] ;
}
};
int main() {
string word1 = "horse";
string word2 = "ros";
Solution ans;
int res = ans.minDistance(word1, word2);
cout << res << endl;
}
python
# 编辑距离
class Solution:
def minDistance(self, word1: str, word2: str) -> int:
# 判断空字符串情况
if not word1:
return len(word2)
if not word2:
return len(word1)
# 初始化dp数组
dp = [[0]*(len(word1)+1) for j in range(len(word2)+1)]
# 初始化第一行和第一列
for i in range(len(word1)+1):
dp[0][i]=i
for i in range(len(word2)+1):
dp[i][0]=i
# 填充dp数组
for j in range(1,len(word2)+1):
for i in range(1,len(word1)+1):
if word1[i-1]==word2[j-1]:
dp[j][i] = dp[j-1][i-1]
else:
dp[j][i] = min(dp[j-1][i-1],dp[j][i-1],dp[j-1][i]) + 1
return dp[-1][-1]
if __name__ == '__main__':
s1 = 'horse'
s2 = 'ros'
ans = Solution()
res = ans.minDistance(s1,s2)
print(res)
岛屿数理(leetcode200)
c++
#include <vector>
#include <iostream>
using namespace std;
// 岛屿数量
class Solution {
public:
int numIslands(vector<vector<char>>& grid) {
// 初始化结果
int res = 0;
// grid的尺寸
int h = grid.size();
int w = grid[0].size();
for(int i=0; i<h;i++){
for(int j=0;j<w;j++){
if (grid[i][j]=='1'){
res++;
dfs(i,j,grid);
}
}
}
return res;
}
void dfs(int i,int j,vector<vector<char>>& grid){
grid[i][j] = '0';
if(i-1>=0 && grid[i-1][j] == '1'){ //向上
dfs(i-1,j,grid);
}
if(i+1<grid.size() && grid[i+1][j] == '1'){ //向下
dfs(i+1,j,grid);
}
if(j-1>=0 && grid[i][j-1] == '1'){ //向左
dfs(i,j-1,grid);
}
if(j+1<grid[0].size() && grid[i][j+1] == '1'){ //向右
dfs(i,j+1,grid);
}
}
};
int main() {
vector<vector<char>> grid = {
{'1','1','1','1','0'},
{'1','1','0','1','0'},
{'1','1','0','0','0'},
{'0','0','0','0','0'}
};
Solution ans;
int res = ans.numIslands(grid);
cout << res << endl;
}
python
# 岛屿数量
from typing import List
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
# 初始化结果
res = 0
# 获取网格大小
m = len(grid)
n = len(grid[0])
# 遍历
for i in range(m):
for j in range(n):
if grid[i][j]=="1":
res+=1
self.dfs(i,j,grid)
return res
def dfs(self,i,j,grid):
grid[i][j] = "0"
if 0<=i-1 and grid[i-1][j] == "1": # 上方
self.dfs(i-1,j,grid)
if i+1<len(grid) and grid[i+1][j] == "1": # 下方
self.dfs(i+1, j, grid)
if 0<=j-1 and grid[i][j-1] == "1": # 左方
self.dfs(i, j-1, grid)
if j+1<len(grid[0]) and grid[i][j+1] == "1": # 右方
self.dfs(i, j+1, grid)
if __name__ == '__main__':
grid = [["1","1","1","1","0"],["1","1","0","1","0"],["1","1","0","0","0"],["0","0","0","0","0"]]
# grid = [["1","1","0","0","0"],["1","1","0","0","0"],["0","0","1","0","0"],["0","0","0","1","1"]]
ans = Solution()
res = ans.numIslands(grid)
print(res)
最大子数组和(leetcode53)
C++
// 最大子数组和
#include <iostream>
#include <vector>
using namespace std;
class Solution {
public:
int maxSubArray(vector<int> &nums) {
// 记录前i-1子数组的最大值
int current=nums[0];
// 记录最大值
int ans = nums[0];
// 遍历当前位置,更新最大值和子数组的最大值
for (int i = 1; i < nums.size(); i++) {
current = current > 0 ? current + nums[i] : nums[i];
ans = max(current,ans);
}
return ans;
}
};
int main() {
vector<int> nums = {5,4,-1,7,8};
Solution ans;
int res = ans.maxSubArray(nums);
cout << res << endl;
return 0;
}
python
# 最大子数组和
from typing import List
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
courrent = -1 # 初始前i-1最大字串和为一个负值,遍历时会被更新
ans = float('-inf') # 初始最大字串和为负无穷
for i in nums: # 遍历更新 前i-1最大字串和、最大字串和
courrent = courrent+i if courrent>0 else i
ans=max(courrent,ans)
return ans
if __name__ == '__main__':
nums = [-2,1,-3,4,-1,2,1,-5,4]
solution = Solution()
ans = solution.maxSubArray(nums)
print(ans)