字符串相加 简单
这道题简单,思路也简单,但要写出简洁的代码还是不容易,记住下面模板
class Solution {
public:
string addStrings(string num1, string num2) {
if (num1.empty()) return num2;
if (num2.empty()) return num1;
int ln1 = num1.length() - 1;
int ln2 = num2.length() - 1;
int carry = 0;
//定义一个空字符串,一边后面插入数字字符
string c = "";
while(carry == 1 || ln1 >= 0 || ln2 >= 0){
//一定要把num1和num2分开考虑,防止出现因两数的位数不同而出现错误
int x = ln1 < 0 ? 0 : num1[ln1--] - '0';
int y = ln2 < 0 ? 0 : num2[ln2--] - '0';
c.insert(c.begin(),(x+y+carry) % 10 +'0');
//carry表示进位
carry = (x+y+carry)/10;
}
return c;
}
};
两数相加 中等
我们用同样的模板来做链表,确实很优秀的一个模板
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
if (l1 == NULL) return l2;
if (l2 == NULL) return l1;
ListNode* res = new ListNode(-1); ListNode* root = res;
int carry = 0;
while (carry == 1 || l1 != NULL || l2 != NULL){
int x = l1==NULL ? 0 : l1->val;
int y = l2==NULL ? 0 : l2->val;
ListNode* node = new ListNode((x+y+carry) % 10);
res->next = node; res = res->next;
carry = (x+y+carry) / 10;
if (l1 != NULL) l1 = l1->next;
if (l2 != NULL) l2 = l2->next;
}
return root->next;
}
};
二叉树的完全性检验 中等
class Solution {
public:
bool isCompleteTree(TreeNode* root) {
if (root == NULL) return true;
queue<TreeNode*> q; q.push(root);
bool hit_final_parent = false;
while (!q.empty()) {
auto node = q.front();
q.pop();
if (node->left != NULL) {
if (hit_final_parent) return false;
q.push(node->left);
}
else
hit_final_parent = true;
if (node->right != NULL) {
if (hit_final_parent) return false;
q.push(node->right);
}
else
hit_final_parent = true;
}
return true;
}
};
前 K 个高频元素 中等
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
if (nums.empty()) return {};
unordered_map<int, int> map;
for (int num:nums) map[num]++;
using Pair = pair<int, int>;
auto mycmp = [](const Pair a, const Pair b){return a.second < b.second;};
priority_queue<Pair, vector<Pair>, decltype(mycmp)> que(mycmp);
for (auto i=map.begin(); i!=map.end(); i++)
que.push(pair<int, int>(i->first, i->second));
vector<int> res;
while (k-- && !que.empty()){
res.push_back(que.top().first);
que.pop();
}
return res;
}
};
手动构建堆,应该构建最小堆,可以自己思考思考
class Solution {
using Pair = pair<int, int>;
void heap(vector<Pair>& nums, int p){
for (int parent=p; parent*2+1<nums.size();){
int child = parent*2+1;
if (child+1<nums.size() && nums[child].second > nums[child+1].second)
child++;
if (nums[parent].second < nums[child].second)
break;
swap(nums[parent], nums[child]);
parent = child;
}
}
void createHeap(vector<Pair>& nums){
for (int i=nums.size()/2; i>=0; i--)
heap(nums, i);
}
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
if (nums.empty()) return {};
unordered_map<int, int> map;
for (int num:nums) map[num]++;
vector<Pair> vec;
for (auto i=map.begin(); i!=map.end(); i++)
vec.push_back(pair<int, int>(i->first, i->second));
vector<Pair> temp(vec.begin(), vec.begin()+k);
createHeap(temp);
for (int i=k; i<vec.size(); i++){
if (temp[0].second < vec[i].second){//这里应该是构建最小堆
temp[0].first = vec[i].first;
temp[0].second = vec[i].second;
heap(temp, 0);
}
}
vector<int> res;
while (!temp.empty()){
res.push_back(temp[0].first);
temp.erase(temp.begin());
heap(temp, 0);
}
return res;
}
};
对称二叉树 简单
class Solution {
bool symmetric(TreeNode* l, TreeNode* r){
if (l == NULL && r == NULL) return true;
if (l == NULL || r == NULL) return false;
if (l->val != r->val) return false;
return symmetric(l->left, r->right) && symmetric(l->right, r->left);
}
public:
bool isSymmetric(TreeNode* root) {
if (root == NULL) return true;
return symmetric(root->left, root->right);
}
};
相同的树 简单
树的模板,也是非常经典的模板
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if (p == NULL && q == NULL) return true;
if (p == NULL || q == NULL) return false;
if (p->val != q->val) return false;
return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
}
};
x的平方根 简单
二分法,细节真的是魔鬼
https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/solution/er-fen-cha-zhao-suan-fa-xi-jie-xiang-jie-by-labula/
通过这个网址学习学习二分法
class Solution {
public:
int mySqrt(int x) {
int l = 0, r = x, ans = -1;
while (l <= r) {
int mid =(r + l) / 2;
if ((long long)mid * mid <= x) {
ans = mid;
l = mid + 1;
}
else {
r = mid - 1;
}
}
return ans;
}
};
旋转数组的最小数字 简单
class Solution {
public:
int minArray(vector<int>& numbers) {
if (numbers.empty()) return -1;
int left=0, right=numbers.size()-1;//[3,4,5,1,2,2,2,2,2]
while (left < right){
int mid = (left + right) / 2;
if (numbers[mid] > numbers[right])
left = mid + 1;
else if (numbers[mid] < numbers[right])
right = mid;
else if (numbers[mid] == numbers[right])
right--;
}
return numbers[left];
}
};
重排链表 中等
链表的题理清思路,在草稿纸上写写就会很清楚了
class Solution {
public:
void reorderList(ListNode* head) {
if (head == nullptr || head->next == nullptr) return;
ListNode* root = head; ListNode* fast = head;
while (fast != nullptr && fast->next != nullptr){
fast = fast->next->next;
head = head->next;
}
ListNode* temp = head->next;//从中间拆分成两个链表
if (temp == nullptr) {head = root; return;}
head->next = nullptr;
stack<ListNode*> stk;//用栈来做
while (temp != nullptr){
stk.push(temp);
temp = temp->next;
}
head = root; ListNode* cur = root; int i=1;
while (!stk.empty()){//开始重排
if (i % 2 == 1) {
root = root->next;
cur->next = stk.top();
stk.pop();
cur = cur->next;
}
else{
cur->next = root;
cur = cur->next;
}
i++;
}
cur->next = root;
}
};
字符串转换整数 (atoi) 中等
思路理清楚就不难
class Solution {
public:
int myAtoi(string str) {//思路理清楚,一步一步来
if (str.empty()) return 0;
while (*str.begin() == ' ') str = str.substr(1);//先去除空格
int flag = 1;
if (*str.begin() == '-') {flag = -1; str = str.substr(1);}//判断符号
else if (*str.begin() == '+') str = str.substr(1);
if (!isdigit(*str.begin())) return 0;//判断是否数字
long long res = 0;
for (int i=0; i<str.length(); i++){
if (!isdigit(str[i])) break;//判断是否数字
res += str[i]-'0';
if (res >= INT_MAX && flag == 1) return INT_MAX;//判断边界
if (res-1 >= INT_MAX && flag == -1) return INT_MIN;
res *= 10;
}
return res*flag/10;
}
};
旋转链表 中等
class Solution {
ListNode* rotate(ListNode* head){
if (head == NULL || head->next == NULL) return head;
ListNode* root = head;
while (root->next->next != NULL){
root = root->next;
}
root->next->next = head;
head = root->next;
root->next = NULL;
return head;
}
public:
ListNode* rotateRight(ListNode* head, int k) {
if (head == NULL || head->next == NULL) return head;
ListNode* root = head; int n=0;
while (root != NULL) {n++; root=root->next;}
for (int i=0; i<k%n; i++){//这里要取模
head = rotate(head);
}
return head;
}
};
剑指 Offer 35. 复杂链表的复制
class Solution {
public:
Node* copyRandomList(Node* head) {
if (head == NULL) return head;
unordered_map<Node*, Node*> map;
Node* root = head;
while (head != NULL){
map[head] = new Node(head->val);
head = head->next;
}
head = root;
while (head != NULL){
map[head]->next = map[head->next];
map[head]->random = map[head->random];
head = head->next;
}
return map[root];
}
};