leetcode算法刷题记录:第一天

很久没刷算法题了,看到题后虽然有印象,但对于边界范围的判断很是吃力,多次提交才通过。记录一下方便后续回顾。

 数组中的第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)

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值