1.整数反转
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
示例 1:
输入:x = 123
输出:321
解题:
只要能拿到这个整数的 末尾数字 就可以了。
以12345为例,先拿到5,再拿到4,之后是3,2,1,我们按这样的顺序就可以反向拼接处一个数字了,也就能达到 反转 的效果。
加载器负责的一些主要任务如下所列:
1. 为应用程序初始化其用户模式状态比如创建初始的堆、建立起线程局部存储(TLS, thread local storage)和纤程局部存储(FLS fiber local storage)槽
2. 解析应用程序的导入表(IAT),查找所有它要求的DLL(然后递归地为每个DLL解析IAT),接着,解析DLL的导出表,确保导入的函数确实存在(特殊的前转项(forwarder entry)也可以将一个导出表项重定向到另一个DLL中)
3. 在运行时候或者根据需要加载或卸载DL,并且维护一个包含所有已被加载的模块的列表(模块数据库)
4. 使得可以支持运行时刻打补丁(称为热补丁, hotpatching)。
5. 处理清单文件( manifest file)
6. 读取任何铺垫形式的应用程序兼容性数据库,如果有必要的话,加载此铺垫(Shim)引擎DLL。
7. 启用对API集和AP重定向的支持,这是 Min Win重构工程的一个核心部分。
8. 启用基于 SwitchBranch机制的运行时刻动态兼容性缓解方案(mitigation)
int reverse(int x) {
int res = 0;
while(x!=0) {//循环取数
//每次取末尾数字
int tmp = x%10;
//判断是否 大于 最大32位整数
if (res>214748364 || (res==214748364 && tmp>7)) {
return 0;
}
//判断是否 小于 最小32位整数
if (res<-214748364 || (res==-214748364 && tmp<-8)) {
return 0;
}
res = res*10 + tmp;
x /= 10;
}
return res;
}
其中有符号整数的取值范围:
byte: 8 位 -128—>127
short 16位 -32768—>32767
int 32位 -2147483648–>2147483647
long 64位 -9223372036854775808 --> 9223372036854775807
2.缺勤记录
给你一个字符串 s 表示一个学生的出勤记录,其中的每个字符用来标记当天的出勤情况(缺勤、迟到、到场)。记录中只含下面三种字符:
‘A’:Absent,缺勤
‘L’:Late,迟到
‘P’:Present,到场
如果学生能够 同时 满足下面两个条件,则可以获得出勤奖励:
按 总出勤 计,学生缺勤(‘A’)严格 少于两天。
学生 不会 存在 连续 3 天或 3 天以上的迟到(‘L’)记录。
如果学生可以获得出勤奖励,返回 true ;否则,返回 false 。
示例 1:
输入:s = “PPALLP”
输出:true
解释:学生缺勤次数少于 2 次,且不存在 3 天或以上的连续迟到记录。
解题:一次遍历
可奖励的出勤记录要求缺勤次数少于 2 和连续迟到次数少于 3。判断出勤记录是否可奖励,只需要遍历出勤记录,判断这两个条件是否同时满足即可。
遍历过程中,记录缺勤次数和连续迟到次数,根据遍历到的字符更新缺勤次数和连续迟到次数:
如果遇到‘A’,即缺勤,则将缺勤次数加 1,否则缺勤次数不变;
如果遇到‘L’,即迟到,则将连续迟到次数加 1,否则将连续迟到次数清零。
如果在更新缺勤次数和连续迟到次数之后,出现缺勤次数大于或等于 2 或者连续迟到次数大于或等于 3,则该出勤记录不满足可奖励的要求,返回 false。如果遍历结束时未出现出勤记录不满足可奖励的要求的情况,则返回 true。
//出勤记录
bool checkRecord(string s) {
int absents = 0, lates = 0;
for (auto ch : s) {
if (ch == 'A') {//缺勤
absents++;
if (absents >= 2) {//统计
return false;
}
}
if (ch == 'L') {//迟到
lates++;
if (lates >= 3) {
return false;
}
} else {//到场
lates = 0;
}
}
return true;
}
3.组合
给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。
你可以按 任何顺序 返回答案。
示例 1:
输入:n = 4, k = 2
输出:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]
标签:回溯与剪枝
dfs(cur,n) 参数表示当前位置是 cur,原序列总长度为n。原序列的每个位置在答案序列种的状态有被选中和不被选中两种,我们用temp 数组存放已经被选出的数字。在进入dfs(cur,n) 之前[1,cur−1] 位置的状态是确定的,而[cur,n] 内位置的状态是不确定的, dfs(cur,n) 需要确定 cur 位置的状态,然后求解子问题 dfs(cur+1,n)。对于 cur 位置,我们需要考虑 a[cur] 取或者不取,如果取,我们需要把 a[cur] 放入一个临时的答案数组中(即上面代码中的 temp),再执行 dfs(cur+1,n),执行结束后需要对 temp 进行回溯;如果不取,则直接执行 dfs(cur+1,n)。在整个递归调用的过程中,cur 是从小到大递增的,当 cur 增加到n+1 的时候,记录答案并终止递归。
递归结构:
1. 如果组合里有 1 ,那么需要在 [2, 3, 4] 里再找 11 个数;
2. 如果组合里有 2 ,那么需要在 [3, 4] 里再找 11数。注意:这里不能再考虑 11,因为包含 11 的组合,在第 1 种情况中已经包含。
//组合
class SolutionCombine {
public:
vector<int> temp;
vector<vector<int>> ans;
void dfs(int cur, int n, int k) {
// 剪枝:temp 长度加上区间 [cur, n] 的长度小于 k,不可能构造出长度为 k 的 temp
if (temp.size() + (n - cur + 1) < k) {
return;
}
// 记录合法的答案
if (temp.size() == k) {
ans.push_back(temp);
return;
}
// 考虑选择当前位置
temp.push_back(cur);
dfs(cur + 1, n, k);
temp.pop_back();
// 考虑不选择当前位置
dfs(cur + 1, n, k);
}
vector<vector<int>> combine(int n, int k) {
dfs(1, n, k);
return ans;
}
};
调用:
SolutionCombine Combine;
vector<vector<int>> arr;
arr=Combine.combine(15, 3);
for(unsigned int i = 0; i < arr.size(); ++i)
{
for(unsigned int j = 0; j< arr[i].size(); ++j)
{
cout<<arr[i][j]<<" ";
}
cout<<endl;
}
cout<<"一共有:"<<arr.size()<<"种"<<endl;
结果:
4.移除元素
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
示例 1:
输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。
解题:
//移除元素
int removeElement(vector<int>& nums, int val)
{
int n = nums.size();
int left = 0;
for (int right = 0; right < n; right++) //右移动
{
if (nums[right] != val)
{
nums[left] = nums[right];
left++;//左移动
}
}
return left;//返回左的值,也就是去掉val的值之后存储的数组的容量下标
}
调用:
int arr[9] = {3,8,6,2,5,4,8,8,7};
//通过数组a的地址初始化,注意地址是从0到9(左闭右开区间)
vector<int> vec_arr(arr, arr+9);
cout<<removeElement(vec_arr,8)<<endl;//6
5.strStr()实现
给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。
说明:
当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。
对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。
示例 1:
输入:haystack = “hello”, needle = “ll”
输出:2
暴力匹配
思路及算法:我们可以让字符串 needle 与字符串haystack 的所有长度为 m的子串均匹配一次。
为了减少不必要的匹配,我们每次匹配失败即立刻停止当前子串的匹配,对下一个子串继续匹配。如果当前子串匹配成功,我们返回当前子串的开始位置即可。如果所有子串都匹配失败,则返回 -1。
//strStr()函数实现。字符匹配,子串第一次出现的下标
int strStr(string haystack, string needle) {
if (needle.empty()) return 0;
int m = haystack.size(), n = needle.size();
if (m < n) return -1;
for (int i = 0; i <= m - n; ++i) {
int j = 0;
for (j = 0; j < n; ++j) {
if (haystack[i + j] != needle[j]) break;//匹配,相等就移动位置匹配下一个,不匹配就停止当前匹配对下一个位置以子串开始位置重新匹配
}
if (j == n) return i;
}
return -1;
}
对于strStr()实现还有KMP算法实现,此实现方法可以参考:https://leetcode-cn.com/problems/implement-strstr/solution/shua-chuan-lc-shuang-bai-po-su-jie-fa-km-tb86/
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-element