目录
思路:使用双指针在两个链表上遍历相加,注意进位的问题。(python and c++)
- # Definition for singly-linked list.
- # class ListNode:
- # def __init__(self, val=0, next=None):
- # self.val = val
- # self.next = next
- class Solution:
- def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
- dummpyHead = ListNode(-1)
- cur = dummpyHead
- tmp,bit,v1,v2 = 0,0,0,0
- while l1 or l2:
- v1 = l1.val if l1 else 0
- v2 = l2.val if l2 else 0
- tmp = v1 + v2 + bit
- dummpyHead.next = ListNode(tmp % 10)
- dummpyHead = dummpyHead.next
- bit = tmp // 10
- if l1: l1 = l1.next
- if l2: l2 = l2.next
- if bit > 0:
- dummpyHead.next = ListNode(bit)
- return cur.next
-
- /**
- * Definition for singly-linked list.
- * struct ListNode {
- * int val;
- * ListNode *next;
- * ListNode() : val(0), next(nullptr) {}
- * ListNode(int x) : val(x), next(nullptr) {}
- * ListNode(int x, ListNode *next) : val(x), next(next) {}
- * };
- */
- class Solution {
- public:
- ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
- ListNode* dummpHead = new ListNode(-1);
- ListNode* cur = dummpHead;
- int tmp = 0,bit = 0,v1 = 0,v2 = 0;
- while (l1 || l2){
- v1 = l1 ? l1->val : 0;
- v2 = l2 ? l2->val : 0;
- tmp = v1 + v2 + bit;
- dummpHead->next = new ListNode(tmp % 10);
- dummpHead = dummpHead->next;
- bit = tmp / 10;
- if (l1) l1 = l1->next;
- if (l2) l2 = l2->next;
- }
- if (bit > 0) dummpHead->next = new ListNode(bit);
- return cur->next;
-
- }
- };
思路:滑动窗口。维护一个集合,将遍历得到的char判断是否在集合中,若在集合中,从左边开始删除元素,一直删除到没有重复元素(使用while),若元素不在集合中,将元素放入到集合中,维护窗口中最多元素数量,当前元素数量,和最左端下标(用来删除元素)。
- class Solution {
- public:
- int lengthOfLongestSubstring(string s) {
- // 滑动窗口
- if (s.empty()) return 0;
- unordered_set<char> window;
- int maxLen = 0,curLen = 0,idx = 0;
- int size = s.length();
- for (int i = 0;i < size;i++){
- curLen++;
- while (window.find(s[i]) != window.end()){
- window.erase(s[idx]);
- idx++;
- curLen--;
- }
- window.insert(s[i]);
- maxLen = max(maxLen,curLen);
- }
- return maxLen;
- }
- };
- class Solution:
- def lengthOfLongestSubstring(self, s: str) -> int:
- # 滑动窗口
- if not s:return 0
- maxLen,curLen,idx = 0,0,0
- window = set()
- for num in s:
- curLen += 1
- while num in window:
- window.remove(s[idx])
- idx += 1
- curLen -= 1
- window.add(num)
- maxLen = max(maxLen,curLen)
- return maxLen
-
注意:python中集合删除元素不能使用pop(),因为pop()是随机删除元素。
思路:使用双指针left 和right,维护一个最大值,不断的移动指针,重点在于移动指针的逻辑,看left 和right指针指向的值,移动指向值小的指针。(python and c++)
- class Solution {
- public:
- int maxArea(vector<int>& height) {
- // 双指针解法
- int n = height.size();
- if (n < 2) return 0;
- int left = 0,right = n-1;
- int maxVolume = 0,volume = 0;
- while (left < right){
- volume = min(height[left],height[right]) * (right-left);
- maxVolume = max(maxVolume,volume);
- if (height[left] > height[right]) right--;
- else left++;
- }
- return maxVolume;
- }
- };
- class Solution:
- def maxArea(self, height: List[int]) -> int:
- # 双指针
- # 边界
- n = len(height)
- if n < 2:return 0
- # 定义指针
- left,right = 0,n-1
- volume = 0
- while left < right:
- volume = max((min(height[left],height[right]) * (right-left)),volume)
- if height[left] < height[right]:
- left += 1
- else:right -= 1
- return volume
时间复杂度:O(n).双指针总共遍历数组一次;
空间复杂度:O(1). 只需要常数级别的空间、
注意:在if-else语句中,else是不能随便省略的,当if (A)为真或者为假时,需要进行处理的时候,就不能省略else关键字,如果对A的真假判断之后不需要处理,则可以省略掉else关键字。
思路:挖坑(现在还不是很明白)
- class Solution:
- def threeSum(self, nums: List[int]) -> List[List[int]]:
- # 排序+双重循环
- n = len(nums)
- if n < 3:return []
- nums.sort()
- ans = []
- for i in range(n):
- if i > 0 and nums[i] == nums[i-1]:continue
- k = n-1
- for j in range(i+1,n):
- if j > i+1 and nums[j] == nums[j-1]:continue
- while j < k and nums[j] + nums[k] > -nums[i]:
- k -= 1
- if j == k: break
- if nums[j] + nums[k] == -nums[i]:
- ans.append([nums[i],nums[j],nums[k]])
- return ans
- class Solution {
- public:
- vector
int>> threeSum(vector<int>& nums) { - // 排序+双重循环
- vector
int>> ans; - int n = nums.size();
- if (n < 3) return ans;
- sort(nums.begin(),nums.end());
- for (int i = 0;i < n;i++){
- if (i > 0 && nums[i] == nums[i-1]) continue;
- int k = n-1;
- for (int j = i+1;j < n;j++){
- if (j > i+1 && nums[j] == nums[j-1]) continue;
-
- while (j < k && nums[i] + nums[j] + nums[k] > 0) k--;
- if (k == j) break;
- if (nums[i] + nums[j] + nums[k] == 0) ans.push_back({nums[i],nums[j],nums[k]});
- }
- }
- return ans;
- }
- };
注意:第三个数字的下标k,应该在第一个循环中定义,不能在循环外面定义,因为第一个数字i每更新一次,就要从最右端开始遍历。