一些零散的算法
C常用数学函数#includeiostream #includecmath using namespace std; int main() { double x 4.0, y 2.0; // 平方根 std::cout sqrt( x ) sqrt(x) std::endl; //sqrt(4) 2 // 幂函数 std::cout pow( x , y ) pow(x, y) std::endl; //pow(4, 2) 16 // 指数函数 (e 的 x 次幂) std::cout exp( x ) exp(x) std::endl; //exp(4) 54.5982 // 以 2 为底的对数 std::cout log2( x ) log2(x) std::endl; // 自然对数 std::cout log( x ) log(x) std::endl; //log(4) 1.38629 // 常用对数以10为底 std::cout log10(100) log10(100) std::endl; //log10(100) 2 double num 3.7; // 向上取整 4 std::cout ceil( num ) ceil(num) std::endl; // 向下取整 3 std::cout floor( num ) floor(num) std::endl; // 四舍五入 4 std::cout round( num ) round(num) std::endl; // 向零取整(就是去掉小数部分 3 std::cout trunc( num ) trunc(num) std::endl; double angle 45.0; // 角度 const double M_PI 3.14159265358979323846; // M_PI 在某些编译环境中可能未定义。这是因为 M_PI 不是 C 标准的一部分 double radian angle * M_PI / 180.0; // 转换为弧度 std::cout sin( angle °) sin(radian) std::endl; std::cout cos( angle °) cos(radian) std::endl; std::cout tan( angle °) tan(radian) std::endl; // 反三角函数 double value 0.5; std::cout asin( value ) asin(value)*180/M_PI ° std::endl; std::cout acos( value ) acos(value)*180/M_PI ° std::endl; std::cout atan( value ) atan(value)*180/M_PI ° std::endl; int a -10, b 3; double c -5.5; std::cout abs( a ) abs(a) std::endl; // 整数绝对值 std::cout fabs( c ) fabs(c) std::endl; // 浮点数绝对值 std::cout fmod(10.5, 3.2) fmod(10.5, 3.2) std::endl; // 浮点数取模 return 0; }数组中两个目标值的最短距离数组中两个字符串的最小距离__牛客网给定一个字符串数组strs再给定两个字符串str1和str2返回在strs中str1和str2的最小距离如果str1或str2为null或不在strs中返回-1。解法遍历数组的同时用两个变量标记当前位置之前的最后出现的 str1 和 str2 的下标。#include iostream #include string #include climits using namespace std; int main() { int n; cin n; string s1,s2;cin s1 s2; if(s1.size() 0 || s2.size() 0) { cout -1 endl; return 0; } int i1 -1,i2 -1; int ret INT_MAX; for(int i 1; i n; i) { string t; cin t; if(t s1) { if(i2 ! -1) ret min(ret,i - i2); i1 i; } else if(t s2) { if(i1 ! -1) ret min(ret,i - i1); i2 i; } } if(ret INT_MAX) cout -1 endl; else cout ret endl; return 0; }两个链表的第一个公共结点除了统计两个链表的长度然后让长的链表的指针先走之外还可以采用这种方式cur1 和 cur2 同时从头结点出发如果 cur1 为空到末尾了就将 cur1 重新从另一个链表的头节点开始遍历cur2 同理。运用了等量关系x1 x x2 x2 x x1该解法和上面提到的解法都可以处理没有公共结点的情况/* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } };*/ class Solution { typedef long long LL; public: ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) { // LL len1 0; // LL len2 0; // ListNode* cur pHead1; // while(cur) // { // if(cur) // { // len1; // cur cur-next; // } // } // cur pHead2; // while(cur) // { // if(cur) // { // len2; // cur cur-next; // } // } // ListNode* cur1 pHead1; // ListNode* cur2 pHead2; // if(len1 len2) // { // LL cnt len1 - len2; // while(cnt--) cur1 cur1-next; // } // else if(len2 len1) // { // LL cnt len2 - len1; // while(cnt--) cur2 cur2-next; // } // while(cur1 ! cur2) // { // cur1 cur1-next; // cur2 cur2-next; // } // return cur1; ListNode* cur1 pHead1; ListNode* cur2 pHead2; while(cur1 ! cur2) { if(cur1) cur1 cur1-next; else cur1 pHead2; if(cur2) cur2 cur2-next; else cur2 pHead1; } return cur1; } };判断一个数是否是 2 的 n 次方方法1不断除 2最终会变成 1方法2二进制表示只有一个“1”其余位都是“0” ---- 统计二进制表示“1” 的个数方法3在方法 2 的基础之上进行 lowbit 操作假设要判断的数是 x如果 x - (x -x) 0 成立则 x 是 2 的 n 次方否则不是方法4在方法 2 的基础之上假设要判断的数是 x如果 x (x - 1) 0成立则 x 是 2 的 n 次方否则不是n 条线段的最多重叠次数题目描述给出 n 条线段的起始坐标和结束坐标判断这 n 条线段的最多重叠次数。解析1、先按照这 n 条线段的起始坐标排序2、创建一个小根堆3、从左往右依次遍历线段最长上升子序列贪心 二分这道题是动态规划的经典题目但它有一个更优的解法时间复杂度为 nlogn这个解法是贪心 二分。解法依次遍历数组在遍历的过程中我们只需要知道长度为 1 的上升子序列的末尾元素、长度为 2 的上升子序列的末尾元素、长度为 3 的上升子序列的末尾元素等等把这些末尾元素记录在 t 数组中t[i] 表示长度为 i 的上升子序列的末尾元素现在假设遍历到了一个新的元素 m 我们就把该元素与上面记录的末尾元素比较如果 m t[i] 说明 m 可以接在 t[i] 后面形成长度为 i 1 的上升子序列再把 m 与 t[i 1] 比较如果 m t[i 1] 仍然成立说明 m 可以接在 t[i 1] 后面形成长度为 i 2 的上升子序列就这样从 t 数组的首元素依次比较直到 i t[j]说明 i 可以接在 t[j - 1] 后面形成长度为 j 的上升子序列并且把 i 赋值给 t[j] 因为 i t[j]这样做可以让后面要遍历的元素更有机会接在 j 的后面因为 t[j] 变成一个比较小的数字 i 了这是体现贪心的地方。我们在比较 i 与 t 数组的元素关系时采用顺序遍历其实可以用二分查找 i 的插入位置i 插入位置其实就是 t[j] i 与 t[j] i 的分界点。在下面的代码中由于二分查找需要确定待查找区间的左右端点刚开始查找时左端点是 0右端点是 ret 1ret 就是最长上升子序列的长度如果最后找到的插入位置是 ret 1那么 retclass Solution { public: /** * 代码中的类名、方法名、参数名已经指定请勿修改直接返回方法规定的值即可 * * 该数组最长严格上升子序列的长度 * param a int整型vector 给定的数组 * return int整型 */ static const int N 1e5 10; int t[N]; int LIS(vectorint a) { // write code here // dp // int sz a.size(); // if(sz 0) return 0; // for(int i 0; i sz; i) dp[i] 1; // for(int i 1; i sz; i) // { // for(int j 0; j i; j) // { // if(a[j] a[i]) dp[i] max(dp[i],dp[j] 1); // } // } // int ret 1; // for(int i 0; i sz; i) ret max(ret,dp[i]); // return ret; // 贪心 二分 int sz a.size(); if(sz 0) return 0; memset(t,0x3f,sizeof(t)); t[1] a[0]; int ret 1; for(int i 1; i sz; i) { int l 1; int r ret 1; while(l r) { int mid l (r - l) / 2; if(t[mid] a[i]) l mid 1; else r mid; } t[l] a[i]; if(l ret 1) ret; } return ret; } };