歧路亡羊是目前的很大敌人,故,统一处理,集中兵力成了我最重要的事情,但凡学习必须专注,否则宁可不学,只有投入和专注才能真正打赢这场仗
疑问:
1.sort函数的[]
优点:
1.从1开始回减,有效控制范围
class Solution { public: bool canAttendMeetings(vectorint>>& intervals) { sort(intervals.begin(), intervals.end(), [](const vector<int>& a, const vector<int>& b){return a[0] < b[0];}); for (int i = 1; i < intervals.size(); ++i) { if (intervals[i][0] < intervals[i - 1][1]) { return false; } } return true; } };
LC278
这道题最重要的是,终止条件的判别。避免陷入死循环。对mid的计算不能直接(left+right)/2,会导致左右太大时,越界,left+(right-left)/2则是一定不会越界的方法,非常好,值得肯定。
此外题干说尽量少用判别函数,所以判别函数虽然也可以决定是否终止,我们应该选择更好的判别方法
// Forward declaration of isBadVersion API. bool isBadVersion(int version); class Solution { public: int firstBadVersion(int n) { int left = 0, right = n; //[left, right] //用这种一定有界的循环,尽量少使用while 1这种情况,避免死循环超时 while (left <= right) { int mid = left + (right - left) / 2; //题干说尽量少使用判断的调用 if (isBadVersion(mid)) { right = mid - 1; } else { left = mid + 1; } } return left; } };
LC283
双指针法,优点:
指针是一种方法名称,并非必须得要指针,用下标一样作用,要领会精神
swap是在std空间的,可以大胆使用
疑问:
swap能交换什么种类的值
答疑:
大部分类型包括vector都可以直接交换
// swap algorithm example (C++98) #include// std::cout #include // std::swap #include // std::vector int main () { int x=10, y=20; // x:10 y:20 std::swap(x,y); // x:20 y:10 std::vector<int> foo (4,x), bar (6,y); // foo:4x20 bar:6x10 std::swap(foo,bar); // foo:6x10 bar:4x20 std::cout << "foo contains:"; for (std::vector<int>::iterator it=foo.begin(); it!=foo.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; return 0; }
class Solution { public: void moveZeroes(vector<int>& nums) { for (int i = 0, j = 0; i < nums.size(); ++i) { if (nums[i]) { swap(nums[i], nums[j++]); } } } };
ps:vector的remove函数只是把后面的数字往前提,但是并不会把要去掉的数字向后挪
eg:1,0,2,0,3
remove(vec.begin(),vec.end(),0)
1,2,3,0,3
后面原来的东西是不变的
解法二虽然写着复杂但时空复杂度与1相似,自带函数比较快
class Solution { public: void moveZeroes(vector<int>& nums) { int n=nums.size(); // if(n==0) return; nums.erase(remove(nums.begin(),nums.end(),0),nums.end()); int n1=nums.size(); if(n1!=n) { vector<int> ad(n-n1,0); nums.insert(nums.end(),ad.begin(),ad.end()); } } };
LC279
四平方数和定理的题,
用原理不具有推广,但是return !!a+!!b是点睛之笔。原本范围很大的int数通过两次取反变成了0/1。使得结果可控
class Solution { public: int numSquares(int n) { while (n % 4 == 0) n /= 4; if (n % 8 == 7) return 4; for (int a = 0; a * a <= n; ++a) { int b = sqrt(n - a * a); if (a * a + b * b == n) { return !!a + !!b; } } return 3; } };
但还是可以用DP做
DP有很多种,这个是和上楼梯一样,不断递推的DP,如何递推,发现问题联系是关键,平方项的应用是点睛之笔
class Solution { public: int numSquares(int n) { vector<int> dp(n+1,INT_MAX); dp[0]=0; //是否带等号很关键,这里初始化了n+1自然可以带 for(int i=0;i<=n;i++) { for(int j=1;i+j*j<=n;j++) { dp[i+j*j]=min(dp[i+j*j],dp[i]+1); } } //vector.back() vector[n]等价,back就是返回最后一个元素 return dp[n]; } };
LC280
摇摆数组,排列是 小 大 小 大。。。依次这种顺序
#include#include #include<string> #include using namespace std; class Solution { public: void wiggleSort(vector<int>& nums) { int n=nums.size(); //先排序,再两两交换 sort(nums.begin(),nums.end());
//从二开始,每次加二 for(int i=2;i2) { swap(nums[i],nums[i-1]); } } }; int main() { vector<int> input={1,2,42,4,1,5,4363,4,6,24}; Solution().wiggleSort(input); for(auto i:input) { cout<endl; } return 0; }
方法二:抓住关键问题,若摇摆,奇偶不同情况,与前一个数的大小情况不同,以此为突破口
#include#include #include<string> #include using namespace std; class Solution { public: void wiggleSort(vector<int>& nums) { //注意判空以及特殊情况 if(nums.size()<=1) return; for(int i=1;i i) { if(i%2==1&&nums[i] 1]||i%2==0&&nums[i]>nums[i-1]) swap(nums[i],nums[i-1]); } } }; int main() { vector<int> input={1,2,42,4,1,5,4363,4,6,24}; Solution().wiggleSort(input); for(auto i:input) { cout<endl; } return 0; }
PS:默认知识点,map内部自动按照key值排序,本身有序,所以无需额外操作,与之对应unordered_map。这次用一个实际代码写出了整体实验流程。通过实际操作来验证知识点是好的行为希望以后发扬光大
#includeusing namespace std; int main() { vector<int> test={1,43,32,31,43,5,42,4,123}; map<int,int> test1; for(auto i:test) { test1[i]++; } for(auto i:test1) cout< endl; return 0; }
最后结果就是把vector中的值排好序的,记得在用map输出值时,要标明是first 还是second的否则会无法输出
PS:
1、什么是堆?
堆是一种非线性结构,(本篇随笔主要分析堆的数组实现)可以把堆看作一个数组,也可以被看作一个完全二叉树,通俗来讲堆其实就是利用完全二叉树的结构来维护的一维数组
按照堆的特点可以把堆分为大顶堆和小顶堆
大顶堆:每个结点的值都大于或等于其左右孩子结点的值
小顶堆:每个结点的值都小于或等于其左右孩子结点的值
(堆的这种特性非常的有用,堆常常被当做优先队列使用,因为可以快速的访问到“最重要”的元素)
默认是大顶堆,小顶堆这样声明
priority_queue, greater > q;