剑指Offer_WEEK02
剑指 Offer 13. 机器人的运动范围
算法(bfs) o(nm)
思路:
这是一个典型的宽度优先搜索问题,我们从 (0, 0) 点开始,每次朝上下左右四个方向扩展新的节点即可。
扩展时需要注意新的节点需要满足如下条件:
- 之前没有遍历过,这个可以用个bool数组来判断
- 没有走出边界
- 横纵坐标的各位数字之和小于 k
最后答案就是所有遍历过的合法的节点个数
每个节点最多只会入队一次,所以时间复杂度不会超过方格中的节点个数
最坏情况下会遍历方格中的所有点,所以时间复杂度就是 o(nm)。
class Solution {
public:
int get_single_num(int x){
int s = 0;
while(x) s += x % 10,x /= 10;
return s;
}
int get_sum(pair<int,int> p){
return get_single_num(p.first) + get_single_num(p.second);
}
int movingCount(int rows, int cols,int threshold)
{
int res = 0;
if(!rows || !cols)
return 0;
vector<vector<bool>> st(rows,vector<bool>(cols));
queue<pair<int,int>> q;
q.push({0,0});
int dx[4] = {-1,0,1,0},dy[4] = {0,1,0,-1};
while(q.size()){
auto t = q.front();
q.pop();
if(get_sum(t) > threshold || st[t.first][t.second])
continue;
res++;
st[t.first][t.second] = true;
for(int i = 0;i < 4;i++){
int x = t.first + dx[i],y = t.second + dy[i];
if(x >= 0 && x < rows && y >= 0 && y < cols){
q.push({x,y});
}
}
}
return res;
}
};
剑指 Offer 14- I. 剪绳子
待补充
剑指 Offer 14- II. 剪绳子 II
待补充
剑指 Offer 15. 二进制中1的个数
算法:位运算 o(logn)
迭代进行如下两步,直到 n变成0为止:
- 如果n在二进制表示下末尾是1,则在答案中加1
- 将n右移一位,也就是将n在二进制表示下的最后一位删掉
这里有个难点是如何处理负数。
在C++中如果我们右移一个负整数,系统会自动在最高位补1,这样会导致 n永远不为0,就死循环了。
解决办法是把 n强制转化成无符号整型,这样 n 的二进制表示不会发生改变,但在右移时系统会自动在最高位补0。
时间复杂度
每次会将n除以2,最多会除 logn 次,所以时间复杂度是O(logn)。
class Solution {
public:
int lowbit(uint32_t x){
return x & -x;
}
int hammingWeight(uint32_t n) {
int cnt = 0;
while(n){
cnt++;
n -= lowbit(n);
}
return cnt;
}
};
剑指 Offer 16. 数值的整数次方
算法:模拟 o(n)
由于本题的指数是int范围,可能很大,所以需要用快速幂求解
注意当指数是负数时,我们需要先取指数的绝对值,最后将乘积的倒数作为答案
时间复杂度
假设指数是 n,则一共会循环 O(logn)次,所以时间复杂度是O(logn)。
class Solution {
public:
double myPow(double x, int n) {
typedef long long LL;
bool is_minus = n < 0;
double res = 1;
for (LL k = abs(LL(n)); k; k >>= 1) {
if (k & 1) res *= x;
x *= x;
}
if (is_minus) res = 1 / res;
return res;
}
};
剑指 Offer 18. 删除链表的节点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* deleteNode(ListNode* head, int val) {
if(!head)
return NULL;
if(head->val == val)
return head->next;
head->next = deleteNode(head->next,val);
return head;
}
};
剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
class Solution {
public:
vector<int> exchange(vector<int>& array) {
vector<int> odd,even;
for(int i = 0;i < array.size();i++){
if(array[i] % 2 == 1)
odd.push_back(array[i]);
else
even.push_back(array[i]);
}
int k = 0;
for(int i = 0;i < odd.size();i++){
array[k++] = odd[i];
}
for(int i = 0;i < even.size();i++){
array[k++] = even[i];
}
return array;
}
};
剑指 Offer 22. 链表中倒数第k个节点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* getKthFromEnd(ListNode* head, int k) {
ListNode* tail = head;
for(int i = 0;i < k - 1;i++){
tail = tail->next;
}
while(tail->next){
tail = tail->next;
head = head->next;
}
return head;
}
};

浙公网安备 33010602011771号