• 【leetcode top100】两数相加。无重复字符的最长子串,盛水最多的容器,三数之和


    目录

    2. 两数相加 - 力扣(LeetCode)

    3. 无重复字符的最长子串 - 力扣(LeetCode)

    11. 盛最多水的容器 - 力扣(LeetCode)

    15. 三数之和 - 力扣(LeetCode)


    2. 两数相加 - 力扣(LeetCode)

     思路:使用双指针在两个链表上遍历相加,注意进位的问题。(python and c++)

    1. # Definition for singly-linked list.
    2. # class ListNode:
    3. # def __init__(self, val=0, next=None):
    4. # self.val = val
    5. # self.next = next
    6. class Solution:
    7. def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
    8. dummpyHead = ListNode(-1)
    9. cur = dummpyHead
    10. tmp,bit,v1,v2 = 0,0,0,0
    11. while l1 or l2:
    12. v1 = l1.val if l1 else 0
    13. v2 = l2.val if l2 else 0
    14. tmp = v1 + v2 + bit
    15. dummpyHead.next = ListNode(tmp % 10)
    16. dummpyHead = dummpyHead.next
    17. bit = tmp // 10
    18. if l1: l1 = l1.next
    19. if l2: l2 = l2.next
    20. if bit > 0:
    21. dummpyHead.next = ListNode(bit)
    22. return cur.next
    1. /**
    2. * Definition for singly-linked list.
    3. * struct ListNode {
    4. * int val;
    5. * ListNode *next;
    6. * ListNode() : val(0), next(nullptr) {}
    7. * ListNode(int x) : val(x), next(nullptr) {}
    8. * ListNode(int x, ListNode *next) : val(x), next(next) {}
    9. * };
    10. */
    11. class Solution {
    12. public:
    13. ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
    14. ListNode* dummpHead = new ListNode(-1);
    15. ListNode* cur = dummpHead;
    16. int tmp = 0,bit = 0,v1 = 0,v2 = 0;
    17. while (l1 || l2){
    18. v1 = l1 ? l1->val : 0;
    19. v2 = l2 ? l2->val : 0;
    20. tmp = v1 + v2 + bit;
    21. dummpHead->next = new ListNode(tmp % 10);
    22. dummpHead = dummpHead->next;
    23. bit = tmp / 10;
    24. if (l1) l1 = l1->next;
    25. if (l2) l2 = l2->next;
    26. }
    27. if (bit > 0) dummpHead->next = new ListNode(bit);
    28. return cur->next;
    29. }
    30. };

    3. 无重复字符的最长子串 - 力扣(LeetCode)

     思路:滑动窗口。维护一个集合,将遍历得到的char判断是否在集合中,若在集合中,从左边开始删除元素,一直删除到没有重复元素(使用while),若元素不在集合中,将元素放入到集合中,维护窗口中最多元素数量,当前元素数量,和最左端下标(用来删除元素)

    1. class Solution {
    2. public:
    3. int lengthOfLongestSubstring(string s) {
    4. // 滑动窗口
    5. if (s.empty()) return 0;
    6. unordered_set<char> window;
    7. int maxLen = 0,curLen = 0,idx = 0;
    8. int size = s.length();
    9. for (int i = 0;i < size;i++){
    10. curLen++;
    11. while (window.find(s[i]) != window.end()){
    12. window.erase(s[idx]);
    13. idx++;
    14. curLen--;
    15. }
    16. window.insert(s[i]);
    17. maxLen = max(maxLen,curLen);
    18. }
    19. return maxLen;
    20. }
    21. };
    1. class Solution:
    2. def lengthOfLongestSubstring(self, s: str) -> int:
    3. # 滑动窗口
    4. if not s:return 0
    5. maxLen,curLen,idx = 0,0,0
    6. window = set()
    7. for num in s:
    8. curLen += 1
    9. while num in window:
    10. window.remove(s[idx])
    11. idx += 1
    12. curLen -= 1
    13. window.add(num)
    14. maxLen = max(maxLen,curLen)
    15. return maxLen

    注意:python中集合删除元素不能使用pop(),因为pop()是随机删除元素。

    11. 盛最多水的容器 - 力扣(LeetCode)

     

    思路:使用双指针left 和right,维护一个最大值,不断的移动指针,重点在于移动指针的逻辑,看left 和right指针指向的值,移动指向值小的指针。(python and c++)

    1. class Solution {
    2. public:
    3. int maxArea(vector<int>& height) {
    4. // 双指针解法
    5. int n = height.size();
    6. if (n < 2) return 0;
    7. int left = 0,right = n-1;
    8. int maxVolume = 0,volume = 0;
    9. while (left < right){
    10. volume = min(height[left],height[right]) * (right-left);
    11. maxVolume = max(maxVolume,volume);
    12. if (height[left] > height[right]) right--;
    13. else left++;
    14. }
    15. return maxVolume;
    16. }
    17. };

     

    1. class Solution:
    2. def maxArea(self, height: List[int]) -> int:
    3. # 双指针
    4. # 边界
    5. n = len(height)
    6. if n < 2:return 0
    7. # 定义指针
    8. left,right = 0,n-1
    9. volume = 0
    10. while left < right:
    11. volume = max((min(height[left],height[right]) * (right-left)),volume)
    12. if height[left] < height[right]:
    13. left += 1
    14. else:right -= 1
    15. return volume

    时间复杂度:O(n).双指针总共遍历数组一次;

    空间复杂度:O(1). 只需要常数级别的空间、

    注意:在if-else语句中,else是不能随便省略的,当if (A)为真或者为假时,需要进行处理的时候,就不能省略else关键字,如果对A的真假判断之后不需要处理,则可以省略掉else关键字。

    15. 三数之和 - 力扣(LeetCode)

     思路:挖坑(现在还不是很明白)

    1. class Solution:
    2. def threeSum(self, nums: List[int]) -> List[List[int]]:
    3. # 排序+双重循环
    4. n = len(nums)
    5. if n < 3:return []
    6. nums.sort()
    7. ans = []
    8. for i in range(n):
    9. if i > 0 and nums[i] == nums[i-1]:continue
    10. k = n-1
    11. for j in range(i+1,n):
    12. if j > i+1 and nums[j] == nums[j-1]:continue
    13. while j < k and nums[j] + nums[k] > -nums[i]:
    14. k -= 1
    15. if j == k: break
    16. if nums[j] + nums[k] == -nums[i]:
    17. ans.append([nums[i],nums[j],nums[k]])
    18. return ans

    1. class Solution {
    2. public:
    3. vectorint>> threeSum(vector<int>& nums) {
    4. // 排序+双重循环
    5. vectorint>> ans;
    6. int n = nums.size();
    7. if (n < 3) return ans;
    8. sort(nums.begin(),nums.end());
    9. for (int i = 0;i < n;i++){
    10. if (i > 0 && nums[i] == nums[i-1]) continue;
    11. int k = n-1;
    12. for (int j = i+1;j < n;j++){
    13. if (j > i+1 && nums[j] == nums[j-1]) continue;
    14. while (j < k && nums[i] + nums[j] + nums[k] > 0) k--;
    15. if (k == j) break;
    16. if (nums[i] + nums[j] + nums[k] == 0) ans.push_back({nums[i],nums[j],nums[k]});
    17. }
    18. }
    19. return ans;
    20. }
    21. };

    注意:第三个数字的下标k,应该在第一个循环中定义,不能在循环外面定义,因为第一个数字i每更新一次,就要从最右端开始遍历。

  • 相关阅读:
    【Python】PyWebIO 初体验:用 Python 写网页
    MySQL-锁
    java与es8实战之五:SpringBoot应用中操作es8(带安全检查:https、账号密码、API Key)
    Linux学习--MySQL学习之查询语句
    决策树算法之鸢尾花特征分类可视化详解【机器学习】
    专家建议|2022内容运营的5大SEO错误以及如何避免
    MySQL架构介绍与说明
    广告学概论试题总汇
    js 对象数组删除某一个特定的对象
    JDK -- IO
  • 原文地址:https://blog.csdn.net/weixin_51449137/article/details/127034043