普通版 剑指 Offer 浅刷浅刷( 四 )


//方法一:class Solution {public:int hammingWeight(uint32_t n) {int num = 0;while (n) {if (n & 1) {num += 1;}n = n >> 1;}return num;}};//方法二:class Solution {public:int hammingWeight(uint32_t n) {if (!n) {return 0;}return (n & 1) + hammingWeight(n >> 1);}};
方法一:每一位直接和1进行&运算,然后再让n左移一位,一直到为0,结束循环并返回统计数 。
方法二:方法一的升级版,递归,学以致用 。
剑指 Offer 16. 数值的整数次方
//方法一:class Solution {public:double fastMultiplication(double x, int n) {if (n == 0) {return 1;}double y = fastMultiplication(x, n / 2);return n % 2 ? y * y * x : y * y;}double myPow(double x, int n) {if (n < 0) {return 1 / fastMultiplication(x, n);} else {return fastMultiplication(x, n);}}};
方法一:快速幂 + 递归,很牛逼 。
剑指 Offer 17. 打印从1到最大的n位数
class Solution {public:vector printNumbers(int n) {vector myVector;for (int i = 1; i < pow(10, n); i++) {myVector.push_back(i);}return myVector;}};
这种题面试的时候应该不会考,太没有水准了,应该考虑的是有大数问题的,返回为类型的,这种问题就的使用全排列进行解答了,对每一位进行0~9的定位,同时要注意的是去零操作 。
剑指 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->val == val) {return head->next;}ListNode *t = head;while (t->next != NULL) {if (t->next->val == val) {t->next = t->next->next;break;} else {t = t->next;}}return head;}};
简单的删除节点,没啥好说的,不过没用双指针 。
剑指 Offer 19. 正则表达式匹配
class Solution {public:bool isMatch(string s, string p) {int m = s.size() + 1, n = p.size() + 1;vector> dp(m, vector(n, false));dp[0][0] = true;// 初始化首行for(int j = 2; j < n; j += 2)dp[0][j] = dp[0][j - 2] && p[j - 1] == '*';// 状态转移for(int i = 1; i < m; i++) {for(int j = 1; j < n; j++) {if(p[j - 1] == '*') {if(dp[i][j - 2]) dp[i][j] = true;// 1.else if(dp[i - 1][j] && s[i - 1] == p[j - 2]) dp[i][j] = true; // 2.else if(dp[i - 1][j] && p[j - 2] == '.') dp[i][j] = true;// 3.} else {if(dp[i - 1][j - 1] && s[i - 1] == p[j - 1]) dp[i][j] = true;// 1.else if(dp[i - 1][j - 1] && p[j - 1] == '.') dp[i][j] = true;// 2.}}}return dp[m - 1][n - 1];}};//写的是真的牛,看了好长时间才理解了人家的思路 。//他是使用 * 来分开的两种情况,再加上dp动态规划的思路dp[0][0]就表示串为空的情况,实际上是从dp[1][1]开始的,dp[i][j]表示s[i]和p[j]的匹配情况//第一种 p[j] 是 *,下列任一情况都是true/*1.dp[i][j - 2]: 即使用 * 的可以将前边字符看作出现0次的特性,就表示删去字符 p[j - 2] 和 * 看删去这两个字符后之前的字符还能否匹配;2.dp[i - 1][j] 且 s[i - 1] = p[j - 2]: 即使用 * 让字符 p[j - 2] 多出现 1 次时,看是否还能匹配;3.dp[i - 1][j] 且 p[j - 2] = '.': 即使用 * 让万能字符 '.' 多出现 1 次时,看是否还能匹配;*///第二种 p[j] 不是 *,下列任一情况都是true/*1.dp[i - 1][j - 1] 且 s[i - 1] = p[j - 1]: 即在上一次字符匹配成功的前提下,再进行新的匹配,看其能否匹配;2.dp[i - 1][j - 1] 且 p[j - 1] = '.': 即因为 . 是万能字符,所以只要上一次匹配成功了,然后这次要匹配的 p[j - 1] 字符是否是 . 这个万能符,是就表示再次匹配成功;*/