1-10
1、反转链表
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* cur = head;
ListNode* pre = nullptr;
while(cur){
ListNode* tmp = cur->next;
cur->next = pre;
pre = cur;
cur = tmp;
}
return pre;
}
};
2、二叉树的右视图
给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
class Solution{
public:
vector<int> rightSideView(TreeNode* root) {
vector<int> res;
if(root == nullptr) return res;
queue<TreeNode*> queue;
queue.push(root);
while(!queue.empty()){
int n = queue.size();
for(int i = 0; i < n; i++){
TreeNode* node = queue.front();
queue.pop();
if(node->left) queue.push(node->left);
if(node->right) queue.push(node->right);
if(i == n - 1) res.push_back(node->val);
}
}
return res;
}
};
3、二叉树的层序遍历
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。
class Solution{
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
vector<int> tmp;
if(root == nullptr) return res;
queue<TreeNode*> queue;
queue.push(root);
while(!queue.empty()){
int n = queue.size();
for(int i = 0; i < n; i++){
TreeNode* node = queue.front();
queue.pop();
tmp.push_back(node->val);
if(node->left) queue.push(node->left);
if(node->right) queue.push(node->right);
}
res.push_back(tmp);
tmp.clear();
}
return res;
}
};
4、二叉树的最大深度
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
class Solution{
public:
int maxDepth(TreeNode* root) {
int res = 0;
if(root == nullptr) return res;
return max(maxDepth(root->left), maxDepth(root->right)) + 1;
}
};
5、删除链表的倒数第N个结点
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
class Solution{
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
if(head == nullptr) return head;
ListNode* slow = head;
ListNode* fast = head;
while(n--){
fast = fast->next;
}
if(fast == nullptr) return head->next;
while(fast->next){
fast = fast->next;
slow = slow->next;
}
slow->next = slow->next->next;
return head;
}
};
6、搜索旋转排序数组
整数数组 nums 按升序排列,数组中的值 互不相同 。
在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], …, nums[n-1], nums[0], nums[1], …, nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。
给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。
class Solution{
public:
int search(vector<int>& nums, int target) {
if(nums.size() == 0 || target == nums[0]) return 0;
int left = 0, right = nums.size() - 1;
int mid = 0;
while(left < right){
int mid = (left + right) / 2;
if(target == nums[left]) return left;
if(target == nums[right]) return right;
if(target == nums[mid]) return mid;
if(nums[mid] > nums[left]){
if(target > nums[mid]) left = mid + 1;
else{
if(target > nums[left]) right = mid - 1;
else left = mid + 1;
}
}
else{
if(target > nums[mid]){
if(target > nums[right]) right = mid - 1;
else left = mid + 1;
}
else
right = mid - 1;
}
}
return -1;
}
};
7、LRU缓存机制
运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制 。
实现 LRUCache 类:
LRUCache(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存
int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
void put(int key, int value) 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字-值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。
class LRUCache{
public:
int cap;
list<pair<int, int>> l1;
unordered_map<int, list<pair<int, int>>::iterator> map;
LRUCache(int capacity) : cap(capacity){}
int get(int key){
if(map.find(key) != map.end()){
auto tmp = *map[key];
l1.erase(map[key]);
l1.push_front(tmp);
map[key] = l1.begin();
return tmp.second;
}
else
return -1;
}
void put(int key, int value){
if(map.find(key) != map.end())
l1.erase(map[key]);
else{
if(l1.size() == cap){
map.erase(l1.back().first);
l1.pop_back();
}
}
l1.push_front({key, value});
map[key] = l1.begin();
}
};
8、三数之和
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
class Solution{
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;
if(nums.size() == 0) return res;
sort(nums.begin(), nums.end());
for(int i = 0; i < nums.size(); i++){
if(i >= 1 && nums[i] == nums[i - 1]) continue;
if(nums[i] > 0) break;
int l = i + 1, r= nums.size() - 1;
while(l < r){
if(nums[i] + nums[l] + nums[r] > 0) r--;
else if(nums[i] + nums[r] + nums[l] < 0) l++;
else{
res.push_back({nums[i], nums[l], nums[r]});
l++;
r--;
while(l < r && nums[l] == nums[l - 1]) l++;
while(l < r && nums[r] == nums[r + 1]) r--;
}
}
}
return res;
}
};
9、二叉树的中序遍历
给定一个二叉树的根节点 root ,返回它的 中序 遍历。
class Solution{
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
dfs(root, res);
return res;
}
void dfs(TreeNode* root, vector<int> &res){
if(root == nullptr) return;
dfs(root->left, res);
res.push_back(root->val);
dfs(root->right, res);
}
};
10、二分查找
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
class Solution{
public:
int search(vector<int>& nums, int target) {
int mid = 0, left = 0, right = nums.size() - 1;
while(left <= right){
int mid = (left + right) / 2;
if(nums[mid] > target) right = mid - 1;
else if(nums[mid] < target) left = mid + 1;
else return mid;
}
return -1;
}
};