目录
给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
思路:
在python中可以使用collection模块进行计数,collections.Counter().most_common(),返回的是dict(),key 是num,value是出现的次数。
class Solution:
def majorityElement(self, nums: List[int]) -> int:
# python 还可以使用特有collection模块去计数
count = collections.Counter(nums).most_common()
return count[0][0]
可以使用哈希表,将num和出现的次数存储,最后找到出现次数大于n/2的元素。
class Solution:
def majorityElement(self, nums: List[int]) -> int:
count = dict()
for num in nums:
count[num] = count.get(num,0) + 1 # 这一行重要
if count[num] > len(nums) / 2:
return num
class Solution {
public:
int majorityElement(vector<int>& nums) {
int n = nums.size();
unordered_map<int,int> count;
int key = 0,value = 0;
for (auto& num:nums){
count[num]++;
if (count[num] > value){
value = count[num];
key = num;
}
}
return key;
}
};
206. 反转链表 - 力扣(LeetCode)
给你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
思路:
双指针迭代。
画图的方式可以很好理解,定义指针 pre=None,cur = head, tmp = head.next ,遍历整个链表,节点两两反转。
(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 reverseList(self, head: ListNode) -> ListNode:
# 双指针迭代
if not head or not head.next: return head
pre,cur = None,head
while cur:
# tmp = cur.next
# cur.next = pre
# pre = cur
# cur = tmp
cur.next,pre,cur = pre,cur,cur.next
return pre
/**
* 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* reverseList(ListNode* head) {
//双指针
if (head == nullptr || head->next == nullptr) return head;
ListNode* pre = nullptr,*cur = head;
while (cur){
ListNode* tmp = cur->next;
cur->next = pre;
pre = cur;
cur = tmp;
}
return pre;
}
};
递归。可以把迭代改成递归,这样空间复杂度会增加,但是代码更加简洁。通过递归公式让指针走到链表的导数第二个节点,之后进行翻转。(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 reverseList(self, head: ListNode) -> ListNode:
# 递归
if not head or not head.next:return head
tmp = self.reverseList(head.next)
head.next.next = head
head.next = None
return tmp
/**
* 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* reverseList(ListNode* head) {
//递归
if (head == nullptr || head->next == nullptr) return head;
ListNode* tmp = reverseList(head->next);
head->next->next = head;
head->next = nullptr;
return tmp;
}
};
226. 翻转二叉树 - 力扣(LeetCode)
思路:
关于树的问题,第一个应该想到的应该是递归,使用递归的方式找到左右子树叶节点,之后交换。 这里的递归,就是使用的DFS。(c++ and python)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
// 递归
if (!root) return root;
TreeNode* left = invertTree(root->left);
TreeNode* right = invertTree(root->right);
root->right = left;
root->left = right;
//swap(root->left,root->right);
return root;
}
};
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def invertTree(self, root: TreeNode) -> TreeNode:
# DFS
if not root:return root
left = self.invertTree(root.left)
right = self.invertTree(root.right)
root.left = right
root.right = left
return root
BFS。广度优先遍历,每一次把每一层的节点放到队列中,依次拿出,将它的左右节点交换,之后将它的左右节点放入队列中。
(python and c++)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def invertTree(self, root: TreeNode) -> TreeNode:
# BFS
if not root:return root
que = [root]
while que:
tmp = que.pop()
tmp.left,tmp.right = tmp.right,tmp.left
if tmp.left:que.append(tmp.left)
if tmp.right:que.append(tmp.right)
return root
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
// BFS
if (root == nullptr) return root;
queue<TreeNode*> que;
que.push(root);
while (!que.empty()){
TreeNode* cur = que.front();
que.pop();
swap(cur->left,cur->right);
if (cur->left) que.push(cur->left);
if (cur->right) que.push(cur->right);
}
return root;
}
};
234. 回文链表 - 力扣(LeetCode)
思路1:将链表的节点按照顺序放入到列表中,然后使用双指针遍历。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def isPalindrome(self, head: ListNode) -> bool:
# 列表+双指针
seen = []
while head:
seen.append(head.val)
head = head.next
n = len(seen)
left,right = 0,n-1
while left < right:
if seen[left] != seen[right]:
return False
left += 1
right -= 1
return True
/**
* 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:
bool isPalindrome(ListNode* head) {
//列表+双指针
vector<int> seen;
while (head){
seen.push_back(head->val);
head = head->next;
}
int n = seen.size();
int left = 0,right = n-1;
while (left < right){
if (seen[left] != seen[right]) return false;
left++;
right--;
}
return true;
}
};
思路2:使用快慢指针找到中间节点,之后翻转半部分链表,最后双指针遍历。
(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 isPalindrome(self, head: ListNode) -> bool:
# 列表+双指针
pre = head
cur = self.cutList(head)
curReverse = self.reverseList(cur)
#判断是否相同
flag = True
while flag and curReverse:
if pre.val != curReverse.val:flag = False
curReverse = curReverse.next
pre = pre.next
# 链表复原
cur.next = self.reverseList(curReverse)
return flag
def cutList(self,head):
# 找到中间节点
left,right = head,head
while right and right.next:
left = left.next;
right = right.next.next
return left
def reverseList(self,head):
# 翻转后半部分链表
if not head or not head.next: return head
tmp = self.reverseList(head.next)
head.next.next = head
head.next = None
return tmp
/**
* 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 {
private:
ListNode* cutList(ListNode* head){
if (head == nullptr && head->next == nullptr) return head;
ListNode* fast = head,*slow = head;
while (fast && fast->next){
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
ListNode* reverseList(ListNode* head){
if (!head || !head->next) return head;
ListNode* tmp = reverseList(head->next);
head->next->next = head;
head->next = nullptr;
return tmp;
}
public:
bool isPalindrome(ListNode* head) {
//双指针
ListNode* pre = head;
ListNode* cur = cutList(head);
ListNode* curReverse = reverseList(cur);
bool flag = true;
while (flag && curReverse){
if (pre->val != curReverse->val) flag = false;
pre = pre->next;
curReverse = curReverse->next;
}
// cur->next = reverseList(curReverse);
return flag;
}
};
283. 移动零 - 力扣(LeetCode)
思路:使用双指针,将数组中的0元素向后移动。左右指针均指向nums[0],若nums[right] != 0,交换nums[left] 和nums[right]。(python and c++)
class Solution {
public:
void moveZeroes(vector<int>& nums) {
//使用双指针
int left = 0,right = 0;
int n = nums.size();
while (right < n){
if (nums[right] != 0){
int tmp = nums[right];
nums[right] = nums[left];
nums[left] = tmp;
left++;
}
right++;
}
}
};
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
# 双指针解法
left,right = 0,0
n = len(nums)
while right < n:
if nums[right] != 0:
nums[left],nums[right] = nums[right],nums[left]
left += 1
right += 1