剑指offer刷题专栏C++

剑指offer刷题专栏C++

剑指offer 面试题3 数组中重复的数字

#include<iostream>
#include<vector>
#include<stack>

using namespace std;

class Solution {
public:
	int duplicate(vector<int>& nums) {
		int n = nums.size();
		for (auto x : nums) {
			if (x<0 || x>n - 1) return -1;
		}
		for (int i = 0; i < n; i++) {
			if (i != nums[i] && nums[i] != nums[nums[i]]) swap(nums[i], nums[nums[i]]);
			if (i != nums[i] && nums[i] == nums[nums[i]]) return nums[i];

		}
		return -1;
	}
};

int main() {
	//vector<int> s = {2,3,1,0,2,5,3};
	vector<int> s = { 3,1,-10,1,1,4,3,10,1,1 };
	int res = Solution().duplicate(s);
	cout << res << endl;
	system("pause");
	return 0;
}



剑指offer 面试题3 数组中重复的数字2(不修改数组)

#include<iostream>
#include<vector>

using namespace std;

class Solution {
public:
	int getDuplication(vector<int> nums) {
		int n = nums.size();
		int l = 1, r = n - 1;
		//vector<int> s;
		while (l < r) {
			int mid = (l + r) >> 1;
			int s = 0;
			for (auto x : nums) s += x >= 1 && x <= mid;
			if (s > mid - l + 1) r = mid;
			else l = mid + 1;
		}
		return r;
	}
};

int main() {
	vector<int> s = { 2,3,5,4,3,2,6,7 };
	int res = Solution().getDuplication(s);
	cout << res << endl;
	system("pause");
	return 0;
}

剑指offer 面试题4 二维数组中的查找

#include<iostream>
#include<vector>

using namespace std;

class Solution {
public:
	bool searchArray(vector<vector<int>> arr, int target) {
		if (arr.empty() || arr[0].empty()) return false;
		int i = 0, j = arr.size() - 1;
		while (i< arr.size()&&j>=0) {
			if (arr[i][j] == target) return true;
			else if (arr[i][j] > target) j--;
			else i++;
		}
		return false;
	}
};

int main() {
	vector<vector<int>> arr = { {1,2,8,9},{2,4,9,12},{4,7,10,13},{6,8,11,15} };
	int target = 5;
	bool res = Solution().searchArray(arr, target);
	if (res == true)
		cout << "true" << endl;
	else
		cout << "false" << endl;
	system("pause");
	return 0;
}

剑指offer 面试题5 替换空格

code1

#include<iostream>
#include<string>

using namespace std;

class Solution {
public:
	string replaceSpaces(string& str) {
		string res;
		for (auto x : str) {
			if (x == ' ') res += "%20";
			else res += x;
		}
		return res;
	}
};

int main() {
	string str = "We are happy.";
	string res = Solution().replaceSpaces(str);
	cout << res;
	cout << endl;
	system("pause");
	return 0;
}

code2

class Solution 
{
public:
	void replaceSpace(char *str, int length) //str(char*型)是字符串首地址,length是限定长度,自己设定,不是初始字符串的长度
	{
		if (str == NULL||length<=0)
			return;
		int CountOfBlanks = 0;
		int Originallength = 0;
		for (int i = 0; str[i] != '\0'; i++)//遍历字符串,记录空格数和非空格数
		{
			Originallength++;
			if (str[i] == ' ')
				CountOfBlanks++;
		}
		int len = Originallength + 2 * CountOfBlanks;//‘%’‘2’‘0’分别占一个字符
		if (len >length)
			return;
		while (Originallength >= 0 && len > Originallength)
		{
			if (str[Originallength] == ' ')
			{
				str[len--] = '0';
				str[len--] = '2';
				str[len--] = '%';
			}
			else
			{
				str[len--] = str[Originallength];
			}
 
			Originallength--;
		}
	}
};

剑指offer 面试题6 从尾到头打印链表

#include<iostream>
#include<string>
#include<vector>

using namespace std;

struct ListNode {
	int val;
	ListNode* next;
	ListNode(int data) : val(data), next(nullptr){}
};
class Solution {
public:
	vector<int> printListReversingly(ListNode* head) {
		vector<int> res;
		while (head) {
			res.push_back(head->val);
			head = head->next;
		}
		return vector<int>(res.rbegin(), res.rend());
	}
};
void createList(ListNode* head) {
	ListNode* p = head;
	for (int i = 1; i < 10; ++i) {
		ListNode* NewNode = new ListNode(i);
		p->next = NewNode; // 上一个节点指向这个新建立的节点
		p = NewNode; // p节点指向这个新的节点
	}
	return;
}
int main() {
	ListNode* head = new ListNode(0);
	createList(head);
	vector<int> res = Solution().printListReversingly(head);
	for(auto x : res)
	  cout << x;
	cout << endl;
	system("pause");
	return 0;
}

剑指offer 面试题7 重建二叉树

class Solution {
public:
    map <int, int> hash;
    vector<int> preorder, inorder;
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        preorder = pre;
        inorder = vin;
        for(int i = 0; i < vin.size(); i++) hash[inorder[i]]=i;
        return dfs(0, pre.size()-1, 0, vin.size()-1);
    }
    TreeNode* dfs(int pre_l, int pre_r, int vin_l, int vin_r){
        if(pre_l > pre_r) return nullptr;
        auto root  = new TreeNode(preorder[pre_l]);
        int k = hash[root->val];
        auto left = dfs(pre_l+1, pre_l+k-vin_l, vin_l, k-1);
        auto right = dfs(pre_l+k-vin_l+1, pre_r, k+1, vin_r);
        root->left = left, root->right = right;
        return root;
    }
};

剑指offer 面试题8 用两个栈实现队列

code1

class Solution
{
public:
    void push(int node) {
        stack1.push(node);
    }
 void copy(stack<int> &a, stack<int> &b) {
        while (a.size()) {
            b.push(a.top());
            a.pop();
        }
    }
    int pop() {
         while(!stack1.empty()){
            stack2.push(stack1.top());
            stack1.pop();
        }
        int res = stack2.top();
        stack2.pop();
        while(!stack2.empty()){
            stack1.push(stack2.top());
            stack2.pop();
        }
        return res;
    }
private:
    stack<int> stack1;
    stack<int> stack2;
};

code2

class Solution
{
public:
    void push(int node) {
        stack1.push(node);
        
    }
 void copy(stack<int> &a, stack<int> &b) {
        while (a.size()) {
            b.push(a.top());
            a.pop();
        }
    }
    int pop() {
         copy(stack1, stack2);
        int res = stack2.top();
        stack2.pop();
        copy(stack2, stack1);
        return res;
        
    }

private:
    stack<int> stack1;
    stack<int> stack2;
};

剑指offer 面试题9 斐波那契数列

class Solution {
public:
    int Fibonacci(int N) {
        vector<int> res(N+1);
        res[0] = 0;
        res[1] = 1;
        for(int i = 2; i<= N; i++){
            res[i] = res[i-1]+res[i-2];
        }
        return res[N];
    }
};

剑指offer 面试题10 跳台阶

class Solution {
public:
    int jumpFloor(int N) {
        vector<int> res(N+1);
        res[0] = 1;
        res[1] = 1;
        for(int i = 2; i<= N; i++){
            res[i] = res[i-1]+res[i-2];
        }
        return res[N];
    }
};

剑指offer 面试题10 变态跳台阶

class Solution {
public:
    int jumpFloorII(int number) {
        vector<int> res(number+1);
        res[0] = 0;
        res[1] = 1;
        for(int i = 2; i<=number; i++){
            res[i] = 2*res[i-1];
        }
        return res[number];
    }
};

剑指offer 面试题10 矩形覆盖

class Solution {
public:
    int rectCover(int number) {
        if(number==0) return 0;
        vector<int> res(number+1);
        res[0] = 1;
        res[1] = 1;
        for(int i = 2; i <= number; i++){
            res[i] = res[i-1] + res[i-2]; 
        }
        return res[number];
    }
};

剑指offer 面试题11 旋转数组中的最小数字

code1

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

class Solution {
public:
	//基于二分查找算法的快速解法
	int minNumberInRotateArray(vector<int> rotateArray) {
		//其实不应该有空,因为是在牛客网做的题,有一组测试数据是空
		if (rotateArray.empty()) {
			return 0;
		}
		int left = 0;
		int right = rotateArray.size() - 1;
		if (rotateArray[left] < rotateArray[right]) {
			return rotateArray[left];
		}
		while (right > left) {
			int mid = (right + left) / 2;
			int middle = rotateArray[mid];
			int leftNumber = rotateArray[left];
			int rightNumber = rotateArray[right];
			if ((right - left) == 1) {
				return rightNumber;
			}
			//左中右的值全都相等,不能确定在前还是在后,只能遍历查后一个比前一个小就是最小值
			if (middle == leftNumber && middle == rightNumber) {
				for (int i = left; i < right; i++) {
					if (rotateArray[i] > rotateArray[i + 1]) {
						return rotateArray[i + 1];
					}
				}
				//全相等的话直接返回最左值就行了
				return leftNumber;
			}
			else if (middle < leftNumber) {
				right = mid;
			}
			else if (middle > rightNumber) {
				left = mid;
			}
		}
	}
};
int main() {
	vector<int> nums = { 2,2,0,2,2,2,2 };
	int result = Solution().minNumberInRotateArray(nums);
	cout << result << endl;
	system("pause");
	return 0;
}

code2

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

class Solution {
public:
	int minNumberInRotateArray(vector<int> rotateArray) {
		if (rotateArray.empty()) return 0;
		int left = 0, right = rotateArray.size() - 1, res = rotateArray[0];
		while (left < right - 1) {
			int mid = left + (right - left) / 2;
			if (rotateArray[left] < rotateArray[mid]) {
				res = min(res, rotateArray[left]);
				left = mid + 1;
			}
			else if (rotateArray[left] > rotateArray[mid]) {
				res = min(res, rotateArray[right]);
				right = mid;
			}
			else ++left;
		}
		res = min(res, rotateArray[left]);
		res = min(res, rotateArray[right]);
		return res;
	}
};
int main() {
	vector<int> nums = { 2,2,0,2,2,2,2 };
	int result = Solution().minNumberInRotateArray(nums);
	cout << result << endl;
	system("pause");
	return 0;
}

code3

(1) 使数组满足二分条件while(n > 0 && nums[n] == nums[0]) n--;

(2)特殊情况处理
因为 while(n > 0 && nums[n] == nums[0]) n--;
如果是特殊情况,其他情况都会转化到这两种。

int n = nums.size()
例1:
1 2 3 4 5
nums[n] > nums[0]
minNumber = nums[0]

例2:
1
nums[n] == nums[0]
minNumber = nums[0]

(3)二分

class Solution {
public:
    int findMin(vector<int>& nums) {
        if(nums.empty()) return -1;
        int n = nums.size()-1;
        while(n > 0 && nums[n] == nums[0]) n--;
        if(nums[n]>=nums[0]) return nums[0];
        int l = 0, r = n;
        while(l < r){
            int mid = (l + r)>>1;
            if(nums[mid] < nums[0]) r = mid;
            else l = mid + 1;
        }
        return nums[l];
    }
};

旋转数组查找变形(二分)

以log(n)的时间复杂度查找旋转数组中指定k值的索引下标

#include<iostream>
#include<vector>

using namespace std;

int main() {
	vector<int> arr1 = { 8, 10, 2, 4, 5, 7 };
	int k = 10;
	int n = arr1.size();
	int l = 0, r = n - 1;
	while (l < r) {
		int mid = l + r >> 1;
		if (arr1[mid] < arr1[0]) r = mid;
		else l = mid + 1;
	}
	int temp = l;
	l = temp, r = n - 1;
	while (l <= r) {
		int mid = l + r >> 1;
		if (arr1[mid] >= k) {
			if (arr1[mid] == k) {
				cout << mid << endl;
				return mid;
			}
		}
		else l = mid + 1;
	}
	l = 0, r = temp - 1;
	while (l <= r) {
		int mid = l + r >> 1;
		if (arr1[mid] >= k) {
			if (arr1[mid] == k) {
				cout << mid << endl;
				return mid;
			}		
		}
		else l = mid + 1;
	}
	cout << -1;
	system("pause");
	return -1;
}

剑指offer 面试题15 矩阵中的路径

class Solution {
public:
    bool hasPath(vector<vector<char>>& matrix, string str) {
       for(int i = 0; i<matrix.size(); i++)
            for(int j = 0; j<matrix[i].size(); j++)
                    if(dfs(matrix, str, 0, i, j))
                        return true;
        return false;
    }
    bool dfs(vector<vector<char>>& matrix, string& str, int u, int x, int y){
        
        if(matrix[x][y] != str[u]) return false; 
        if(u == str.size()-1) return true;
        int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
        char t = matrix[x][y];
        matrix[x][y] = '*';
        for(int k = 0; k<4; k++){
            int a = x + dx[k], b = y + dy[k];
            if(a>=0 && a<matrix.size() && b>=0 && b<matrix[a].size())
                if(dfs(matrix, str, u+1, a, b)) return true;
        }
        matrix[x][y] = t;
        return false;
    }
};

剑指offer 面试题15 二进制中1的个数

class Solution {
public:
     int NumberOf1(int n){
    int resu = 0;
    //n没减到0就一直循环
    while(n != 0){
        resu++;
        //
        n = (n-1)&n;
    }
    return resu;
}
};

剑指offer 面试题16 数值的整数次方

class Solution {
public:
    double Power(double base, int exponent) {
        int minus = 0;
        double res = 1;
        if(exponent < 0) minus = -1, exponent = -exponent;
        while(exponent--) res *=base;
        if(minus == -1) return res = 1/res;
        return res;
    }
};

剑指offer 面试题19 正则表达式匹配

在这里插入图片描述

code1

class Solution {
public:
    vector<vector<int>>f;
    int n, m;
    bool isMatch(string s, string p) {
        n = s.size();
        m = p.size();
        f = vector<vector<int>>(n + 1, vector<int>(m + 1, -1));
        return dp(0, 0, s, p);
    }

    bool dp(int x, int y, string &s, string &p)
    {
        if (f[x][y] != -1) return f[x][y];
        if (y == m)
            return f[x][y] = x == n;
        bool first_match = x < n && (s[x] == p[y] || p[y] == '.');
        bool ans;
        if (y + 1 < m && p[y + 1] == '*')
        {
            ans = dp(x, y + 2, s, p) || first_match && dp(x + 1, y, s, p);
        }
        else
            ans = first_match && dp(x + 1, y + 1, s, p);
        return f[x][y] = ans;
    }
};

code2

class Solution {
public:
    bool match(char* str, char* pattern)
    {
        if (pattern[0] == 0 && str[0] == 0)
        {
            return true;
        }
   
        if (pattern[0] != 0 && pattern[1] == '*')
        {
            if (match(str, pattern + 2))
                return true;
        }
   
        if ((pattern[0] == '.' && str[0]) || str[0] == pattern[0])
        {
            if (match(str + 1, pattern + 1))
                return true;
            if (pattern[1] == '*' && match(str + 1, pattern))
            {
                return true;
            }
        }
   
        return false;   
    }
};

剑指offer 面试题21 调整数组顺序使奇数位于偶数前面

class Solution {
public:
    bool match(char* str, char* pattern)
    {
        if (pattern[0] == 0 && str[0] == 0)
        {
            return true;
        }
   
        if (pattern[0] != 0 && pattern[1] == '*')
        {
            if (match(str, pattern + 2))
                return true;
        }
   
        if ((pattern[0] == '.' && str[0]) || str[0] == pattern[0])
        {
            if (match(str + 1, pattern + 1))
                return true;
            if (pattern[1] == '*' && match(str + 1, pattern))
            {
                return true;
            }
        }
   
        return false;   
    }
};

剑指offer 面试题21 调整数组顺序使奇数位于偶数前面

code1(奇奇,偶偶,相对位置不变)

class Solution {
public:
    void reOrderArray(vector<int> &array) {
    for(int i = 0; i<array.size(); i++){
        for(int j = array.size()-1; j>i; j--)
            if(array[j]%2 == 1 && array[j-1]%2 == 0)
                swap(array[j], array[j-1]);
    }
  }
};

code2(相对位置无要求)

class Solution {
public:
    void reOrderArray(vector<int> &array) {
         int l = 0, r = array.size() - 1;
         while (l < r) {
             while (l < r && array[l] % 2 == 1) l ++ ;
             while (l < r && array[r] % 2 == 0) r -- ;
             if (l < r) swap(array[l], array[r]);
         }
    }
};

剑指offer 面试题22 链表中倒数第K个节点

class Solution {
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
        ListNode* cur = pListHead;
        int len = 0;
        for(ListNode* p = pListHead; p; p = p->next){
            len++;
        }
        if (len < k) return nullptr;
        for(int i = len-k; i>0; i--){
            cur = cur->next;
        }
return cur;
    }

剑指offer 面试题24 反转链表

class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        ListNode* pre = nullptr;
        ListNode* cur = pHead;
        while(cur){
            auto temp = cur->next;
            cur->next = pre;
            pre = cur;
            cur = temp;
        }
        return pre;
    }
};

剑指offer 面试题25 合并两个有序链表

code

class Solution {
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
        
        ListNode* p1 = pHead1;
        ListNode* p2 = pHead2;
        ListNode newlist(-1);
        ListNode* pNew = &newlist;
        while(p1 && p2){
            if(p1->val < p2->val){
                pNew->next = p1;
                p1 = p1->next;
            }
            else {
                pNew->next = p2;
                p2 = p2->next;
            }
            pNew = pNew->next;
        }
        if(p1) pNew->next = p1;
        if(p2) pNew->next = p2;
        return newlist.next;
    }
};

code2(错误示范)

class Solution {
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
        
        ListNode* p1 = pHead1;
        ListNode* p2 = pHead2;
        ListNode newlist(-1);
        ListNode* pNew = &newlist;
        while(p1 && p2){
            if(p1->val < p2->val){
                pNew->next = p1;
                p1 = p1->next;
            }
            if(p1->val >= p2->val) { #注意:上面p1已经发生移动
                pNew->next = p2;
                p2 = p2->next;
            }
            pNew = pNew->next;
        }
        if(p1) pNew->next = p1;
        if(p2) pNew->next = p2;
        return newlist.next;
    }
};

剑指offer 面试题26 树的子结构

class Solution {
public:
    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
    {
     if(!pRoot1 || !pRoot2) return false;
     if(isPart(pRoot1, pRoot2)) return true;
     return HasSubtree(pRoot1->left, pRoot2)||HasSubtree(pRoot1->right, pRoot2);
    }
    bool isPart(TreeNode* pRoot1, TreeNode* pRoot2){
        if(!pRoot2) return true;
        if(!pRoot1 || pRoot1->val!= pRoot2->val) return false;
        return isPart(pRoot1->left, pRoot2->left) && isPart(pRoot1->right, pRoot2->right);
    }
};

剑指offer 面试题28 对称的二叉树

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
    bool isSymmetrical(TreeNode* root) {
        if(!root) return true;
        return dfs(root->left, root->right);
    bool dfs(TreeNode* p, TreeNode* q){
        if(!p||!q) return !p&&!q;
        if(p->val!=q->val) return false;
        return dfs(p->left, q->right)&&dfs(p->right, q->left);
    }
};

剑指offer 面试题44 数字序列中的某一位数字

class Solution {
public:
    int digitAtIndex(int n) {
        long long i = 1, s = 9, base = 1;

        while(n>i*s){
            n -= i*s;
            i++;
            s *=10;
            base *=10;
        }
        int num = base + (n+i-1)/i - 1;
        int r = n % i ? n % i : i;
        for(int k = 0; k < i-r; k++) num /=10;
        return num % 10; 
    }
};

剑指offer 面试题45 把数组排成最小的数

class Solution {
public:
static bool cmp(int a, int b){
            string sa = to_string(a), sb = to_string(b);
            return sa + sb < sb + sa;
        }
    string printMinNumber(vector<int>& nums) {
       sort(nums.begin(), nums.end(), cmp);
       string res;
       for(auto x : nums) res +=to_string(x);
       return res;
    }
};

剑指offer 面试题46 把数字翻译成字符串

class Solution {
public:
    int getTranslationCount(string s) {
        int n = s.size()-1;
        int res[n];
        res[0] = 1;
        for(int i = 1; i <= n; i++){
        res[i] = res[i-1];
        int t = (s[i-2]-'0')*10 + s[i-1]-'0';
        if(t >= 10 && t <= 25)
        res[i] +=res[i-2];
        }
        return res[n];
    }
};

剑指offer 面试题47 礼物的最大值

class Solution {
public:
    int getMaxValue(vector<vector<int>>& grid) {
        int m = grid.size(), n = grid[0].size();
        int f[m+1][n+1];
        f[0][0] = grid[0][0];
        for(int i = 0; i < m; i++)
            for(int j = 0; j < n; j++){
                if(i == 0 && j == 0) f[i][j] = f[0][0];
                if(i == 0 && j != 0) f[i][j] = f[i][j-1] + grid[i][j];
                if(j == 0 && i != 0) f[i][j] = f[i-1][j] + grid[i][j];
                if(i>0&&j>0) f[i][j] =max(f[i][j-1], f[i-1][j]) + grid[i][j];
            }
        return f[m-1][n-1];      
    }
};

剑指offer 面试题49 丑数

code1

class Solution {
public:
    int GetUglyNumber_Solution(int index) {
        vector<int> UglyNumbers;
        UglyNumbers.push_back(1);
        int index2 = 0;
        int index3 = 0;
        int index5 = 0;
        for(int i = 1; i < index; i++){
        int max_Ugly_2 = UglyNumbers[index2]*2;
        int max_Ugly_3 = UglyNumbers[index3]*3;
        int max_Ugly_5 = UglyNumbers[index5]*5;
        
        int curUgly = min(min(max_Ugly_2, max_Ugly_3), max_Ugly_5);
        UglyNumbers.push_back(curUgly);
        if(curUgly == max_Ugly_2)
            index2++;
        if(curUgly == max_Ugly_3)
            index3++;
        if(curUgly == max_Ugly_5)
            index5++;
        }
        
        return UglyNumbers[index-1];
    }
};

code2

class Solution {
public:
    int getUglyNumber(int n) {
        int f[n+1];
        f[0] = 1;
        for(int i = 0, j = 0, k = 0, m = 1; m < n; m++){
            int cur_2 = f[i]*2;
            int cur_3 = f[j]*3;
            int cur_5 = f[k]*5;
            int cur = min(cur_2, min(cur_3, cur_5));
            f[m] = cur;
            if(cur == cur_2) i++;
            if(cur == cur_3) j++;
            if(cur == cur_5) k++;
        }
        return f[n-1];
    }
};

剑指offer 面试题 50 第一个只出现一次的字符

class Solution {
public:
    char firstNotRepeatingChar(string s) {
        unordered_map<char, int> count;
        for(auto x : s) ++count[x];
        for(auto x : s) 
        if(count[x] == 1) return x;
        return '#';
    }
};

剑指offer 面试题 55 二叉树的深度

class Solution {
public:
    int treeDepth(TreeNode* root) {
        return dfs(root, 0);
    }
    int dfs(TreeNode* root, int depth){
        if(!root) return depth;
        depth++;
        return max(dfs(root->left, depth), dfs(root->right, depth));
    }
};

剑指offer 面试题60 n个骰子的点数

code(DFS)

class Solution {
public:
    vector<int> numberOfDice(int n) {
            vector<int> res;
            for(int j = n; j<=6*n; j++){
                res.push_back(dfs(n, j));
            }
            return res;
    }
    int dfs(int n, int sum){
        if(n<0) return 0;
        if(n==0) return !sum;
        int res = 0;
        for(int i = 1; i <= 6; i++){
            res += dfs(n-1, sum-i);
        }
        return res;
    }
};

code(DP)

class Solution {
public:
    vector<int> numberOfDice(int n) {
          
           vector<vector<int>> f(n+1, vector<int>(6*n+1));
           f[0][0] = 1;
           for(int i = 1; i<=n; i++){
               for(int j = 1; j<=6*n; j++){
                   for(int k = 1; k <= min(6, j); k++){
                       f[i][j] +=f[i-1][j-k];
                   }
               }
           }
           vector<int> res;
           for(int i = n; i<=6*n; i++) res.push_back(f[n][i]);
           return res;
    }      
};

剑指offer 面试题61 扑克牌中的顺子

class Solution {
public:
    bool IsContinuous( vector<int> numbers ) {
        if(numbers.empty()) return false;
        int k = 0;
        int n = numbers.size();
        sort(numbers.begin(), numbers.end());
        while(!numbers[k]) k++;
        for(int i = k+1; i < n; i++){
            if(numbers[i]==numbers[i-1]) return false;
            
        }
        return numbers.back()-numbers[k] <= 4;
    }
};

剑指offer 面试题62 圆圈中最后剩下的数字

code1

class Solution {
public:
    int lastRemaining(int n, int m){
        return dfs(n, m);
    }
    int dfs(int n, int m){
        if(n==1) return 0;
        else return (dfs(n-1, m) + m)%n;
    }
};

code2

class Solution {
public:
    int LastRemaining_Solution(int n, int m)
    {
        if(n==0) return -1;
        int s=0;
        for(int i=2;i<=n;i++){
            s=(s+m)%i;
        }
        return s;
    }
};

剑指offer 面试题64 求1+2+…n

class Solution {
public:
    int res = 0;
    int getSum(int n) {
        res += n; 
        n!=0&&getSum(n-1);
        return res;
    }
};

剑指offer 面试题65 不用加减乘除做加法

class Solution {
public:
    
    int add(int num1, int num2)
    {
        int carry;
        int units;
        while(num2){
            carry = num1&num2;
            units = num1^num2;
            num1 = units;
            num2 = carry<<1;
        }
        return num1;
    }
};

剑指offer 面试题66 构建乘积数组

class Solution {
public:
    vector<int> multiply(const vector<int>& A) {
       int len = A.size();
        if(A.empty()) return {};
        vector<int> B(len, 1);
        for(int k = 0; k < len; k++){
            for(int i = 0; i < k; i++){
                B[k] *= A[i];
            }
            for(int j = len-1; j > k; j--){
                B[k] *= A[j];
            }
        }
        return B;
    }
};

剑指offer 面试题67 把字符串转换成整数

code1

class Solution {
public:
    int strToInt(string str) {
        if(str.empty()) return 0;
        int n = str.size();
        long long res = 0;
        int k = 0;
        bool isminus = false;
        while(k < n && str[k]==' ') k++;
        if(str[k] == '+') k++;
        else if(str[k] == '-') isminus = true, k++;
        while(str[k] >= '0' && str[k] <= '9') res = res*10 + str[k]-'0', k++;  
        if(isminus) res *= -1;
        if(res > INT_MAX) res = INT_MAX ;
        if(res < INT_MIN) res = INT_MIN;
        return res;
    }
};

code(牛客剑指offer:把字符串转化成整数)

class Solution {
public:
    int StrToInt(string str) {
        if (str.empty()) return 0;
        int sign = 1, base = 0, i = 0, n = str.size();
        while (i < n && str[i] == ' ') ++i;
        if (i < n && (str[i] == '+' || str[i] == '-')) {
            sign = (str[i++] == '+') ? 1 : -1;
        }
        while(str[i] != '\0'){
            if(i < n && str[i] >= '0' && str[i] <= '9') {
                if (base > INT_MAX / 10 || (base == INT_MAX / 10 && str[i] - '0' > 7)) {
                return (sign == 1) ? INT_MAX : INT_MIN;
                }
                base = 10 * base + (str[i++] - '0');
                }
            else{
                base = 0;
                break;
            }
        }
        return base * sign;
    }
};

剑指offer 面试题68 树中两个节点的最低公共祖先

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(!root) return nullptr;
        if(root==p||root==q) return root;
        TreeNode* left = lowestCommonAncestor(root->left, p, q);
        TreeNode* right = lowestCommonAncestor(root->right, p, q);
        if(left&&right) return root;
        if(left) return left;
        else return right;
    }
};

剑指offer 面试题 滑动窗口的最大值

class Solution {
public:
    vector<int> maxInWindows(const vector<int>& num, unsigned int size)
    {
        vector<int> res;
        if(num.empty()||size>num.size()||size<1)
            return res;
        multiset<int> st;
        for(int i = 0; i < num.size(); i++){
            if(i>=size) st.erase(st.find(num[i-size]));
            st.insert(num[i]);
            if(i>=size-1) res.push_back(*st.rbegin());
        }
        return res;
    }
};

剑指offer 面试题 0到n-1中缺失的数字(二分发)

class Solution {
public:
    int getMissingNumber(vector<int>& nums) {
        int l = 0, r = nums.size();
        sort(nums.begin(), nums.end());
        while(l < r){
            int mid = (l+r)>>1;
            if(nums[mid] > mid) r = mid;
            else l = mid+1;
        }
        return l;
    }
};

剑指offer 面试题 数组中数值和下标相等的元素

class Solution {
public:
    int getNumberSameAsIndex(vector<int>& nums) {
        int l = 0, r = nums.size()-1;
        while(l < r){
            int mid = (l + r)>>1;
            if(nums[mid] == mid) return mid;
            if(nums[mid] > mid) r = mid;
            else l = mid + 1;
        }
        if (nums[l] == l) return l;
        return -1;
    }
};

剑指offer 面试题 二叉搜索树的第k个结点

class Solution {
public:
    int count = 0;
    TreeNode* ans;
    TreeNode* kthNode(TreeNode* root, int k) {
        dfs(root, k); 
        return ans;
    }
    TreeNode* dfs(TreeNode* root, int k){
        if(!root) return nullptr;
        dfs(root->left, k);
        count++;
        if(count == k) return ans = root;
        dfs(root->right, k);
    }
};

剑指offer 面试题 平衡二叉树

class Solution {
public:
    bool isBalanced(TreeNode* root) {
        //if(!root) return true;
        int dmax = dfsMax(root, 0);
        int dmin = dfsMin(root, 0);
        return (dmax-dmin)<=1;
    }
    int dfsMax(TreeNode* root, int depth){
        if(!root) return depth;
        depth++;
        return max(dfsMax(root->left, depth), dfsMax(root->right, depth));
    }
    int dfsMin(TreeNode* root, int depth){
        if(!root) return depth;
        depth++;
        return min(dfsMin(root->left, depth), dfsMin(root->right, depth));
    }
};

剑指offer 面试题 数组中只出现一次的数字

code1

class Solution {
public:
    void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
        int sum = 0;
        for(auto x : data) sum ^=x;
        int k = 0;
        while(!(sum>>k & 1))k++;
        int first = 0;
        for(auto x: data)
            if(x>>k&1)
                first ^= x;
        *num1 = first;
        *num2 = sum^first;
    }
};

code2

class Solution {
public:
    void FindNumsAppearOnce(vector<int> data, int* num1, int *num2){
	if (data.size() < 2)
		return;
	map<int, int> hash;
 
	for (int i = 0; i < data.size();i++)
	{
		hash[data[i]]++;
	}
	vector<int> res;
	for (int i = 0; i < data.size(); i++)
	{
		if (hash[data[i]] == 1)
			res.push_back(data[i]);
		
		if (res.size() == 2)
			break;
	}
	*num1 = res[0];
	*num2 = res[1];
}
};

code3

class Solution {
public:
    vector<int> findNumsAppearOnce(vector<int>& nums) {

    vector<int> b;
    std::sort(nums.begin(),nums.end());

    for(int i=0;i<nums.size();){
        if(nums[i]==nums[i+1])
            i += 2;
        if (nums[i]!=nums[i+1]){
            b.push_back(nums[i]);
            i +=1;
        if(b.size()==2)return b;

        }
    }
}
};

code4

class Solution {
public:
    vector<int> findNumsAppearOnce(vector<int>& data) {

    set<int> save;
	set<int>::iterator iter;
	for (int i = 0; i < data.size(); i++){
		if (save.find(data[i]) == save.end())
			save.insert(data[i]);
		else{
			iter = save.find(data[i]);
			save.erase(iter);
		}
	}
	vector<int> res(2);
	iter = save.begin();
	res[0] = *iter;
    res[1] = *(++iter);
    return res;
}
};

剑指offer 面试题 数组中唯一只出现一次的数字

class Solution {
public:
    int findNumberAppearingOnce(vector<int>& nums) {
        int res;
        sort(nums.begin(), nums.end());
        for(int i = 0; i < nums.size();){
            if(nums[i] == nums[i+2]) i +=3;
            else return nums[i];
        }
    }
};

code1(暴力搜索)

class Solution {
public:
    vector<int> findNumbersWithSum(vector<int>& nums, int target) {
        for(int i = 0; i < nums.size(); i++){
            for(int j = 0; j < nums.size(); j++){
                if(nums[j] == target-nums[i]) return vector<int> {nums[j], nums[i]};
            }
        }
    }
};

code2(双指针法)

class Solution {
public:

    vector<int> findNumbersWithSum(vector<int>& nums, int target) {
        sort(nums.begin(),nums.end());
        for(int i = 0 ,j = nums.size() - 1; i <j;){
            if(nums[i] +nums[j] == target)
               return  vector<int>{nums[i],nums[j]};
            else if(nums[i] + nums[j] < target)
                i++;
            else 
                j--;
        }
    }
};

剑指offer 面试题 左旋转字符串

class Solution {
public:
    string leftRotateString(string str, int n) {
        if(n > str.size()) return str;
        return  str.substr(n) + str.substr(0, n);
    }
};

剑指offer 面试题 反转单词顺序

class Solution {
public:
    string reverseWords(string s) {
        reverse(s.begin(), s.end());
        for(int i = 0; i < s.size(); i++){
            int j = i;
            while(j < s.size() && s[j] != ' ') j++;
            reverse(s.begin()+i, s.begin()+j);
            i = j;
        }
        return s;
    }
};

剑指offer 面试题 和为S的连续正数序列

class Solution {
public:
    vector<vector<int> > findContinuousSequence(int sum) {
        vector<vector<int>> res;
        for(int i = 1, j = 1, s = 1; i <= sum; i++){
             while(s < sum)j++, s += j;
        if(s == sum && j-i > 0){
            vector<int> path;
            for(int k = i; k <= j; k++) path.push_back(k);
            res.push_back(path);
        }
        s -=i;
        }
       return res;
    }
};

剑指offer 面试题 最长不含重复字符的子字符串

class Solution {
public:
    int longestSubstringWithoutDuplication(string s) {
        unordered_map<char, int> count;
        int res = 0;
        for(int i = 0, j = 0; j < s.size(); j++){
            if(++count[s[j]]>1) {
                while(count[s[i]] == 1) count[s[i++]]--;
                count[s[i++]]--;
            }
            res = max(res, j - i + 1);
        }
        return res;
    }
};

剑指offer 面试题 字符流中第一次只出现一次的字符

class Solution{
public:
    unordered_map<char, int> count;
    queue<char> q;
    //Insert one char from stringstream
    void insert(char ch){
        if(++count[ch] > 1) 
        while(q.size() && count[q.front()] > 1) q.pop();
        else q.push(ch);
    }
    //return the first appearence once char in current stringstream
    char firstAppearingOnce(){
        if(q.empty()) return '#';
        return q.front();
    }
};

剑指offer 面试题 数字在排序数组中出现的次数

class Solution {
public:
    int GetNumberOfK(vector<int> data ,int k) {
        if(data.empty()) return 0;
        int l = 0, r = data.size()-1;
        while(l<r){
            int mid = (l+r)>>1;
            if(data[mid]<k) l = mid + 1;
            else r = mid;
        }
        if(data[l]!=k) return 0;
        int left = l;
        l = 0, r = data.size()-1;
        while(l<r){
            int mid = (l+r+1)>>1;
            if(data[mid]<=k) l = mid;
            else r = mid - 1;
        }
        return r - left + 1;
    }
};

剑指offer 面试题 两个链表的第一个公共结点

class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        auto l1 = pHead1, l2 = pHead2;
        while(l1!=l2){
            if(l1) l1 = l1->next;
            else l1 = pHead2;
            if(l2) l2 = l2->next;
            else l2 = pHead1;
        }
        return l1;
    }
};

剑指offer 面试题 数组中的逆序对

class Solution {
public:
    int InversePairs(vector<int> data) {
       int length=data.size();
        if(length<=0)
            return 0;
       //vector<int> copy=new vector<int>[length];
       vector<int> copy;
       for(int i=0;i<length;i++)
           copy.push_back(data[i]);
       long long count=InversePairsCore(data,copy,0,length-1);
       //delete[]copy;
       return count%1000000007;
    }
    long long InversePairsCore(vector<int> &data,vector<int> &copy,int start,int end)
    {
       if(start==end)
          {
            copy[start]=data[start];
            return 0;
          }
       int length=(end-start)/2;
       long long left=InversePairsCore(copy,data,start,start+length);
       long long right=InversePairsCore(copy,data,start+length+1,end); 
        
       int i=start+length;
       int j=end;
       int indexcopy=end;
       long long count=0;
       while(i>=start&&j>=start+length+1)
          {
             if(data[i]>data[j])
                {
                  copy[indexcopy--]=data[i--];
                  count=count+j-start-length;          //count=count+j-(start+length+1)+1;
                }
             else
                {
                  copy[indexcopy--]=data[j--];
                }          
          }
       for(;i>=start;i--)
           copy[indexcopy--]=data[i];
       for(;j>=start+length+1;j--)
           copy[indexcopy--]=data[j];       
       return left+right+count;
    }
};

剑指offer 面试题 机器人的运动范围

class Solution {
public:

int get_sum(pair<int, int> p){
    int s = 0;
    while(p.first){
        s += p.first % 10;
        p.first /= 10;
    }
    while(p.second){
        s += p.second % 10;
        p.second /= 10;
        
    }
    return s;
    
}
    int movingCount(int threshold, int rows, int cols)
    {
        if(!rows || !cols) return 0;
        int res = 0;
        queue<pair<int, int>> q;
        vector<vector<bool>> st(rows, vector<bool>(cols));
        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();
            int x = t.first, y = t.second;
            if(st[x][y]||get_sum(t) > threshold) continue;
            res++;
            st[x][y] = true;
            for(int k = 0; k < 4; k++){
                
            int a = x + dx[k], b = y + dy[k];
            if(a>=0&&a<rows&&b>=0&&b<cols) q.push({a, b});
        }
        }
        return res;
        
    }
};

剑指offer 面试题 剪绳子

class Solution {
public:
    int maxProductAfterCutting(int n) {
        int res = 1;
        if(n <= 3) return 1*(n-1);
        if(n % 3 == 1) res = 4, n -= 4;
        else if (n % 3 == 2) res = 2, n -=2;
        while(n) res *= 3, n -= 3;
        return res;
    }
};

剑指offer 面试题 链表中环的入口结点

class Solution {
public:
    ListNode *entryNodeOfLoop(ListNode *head) {
        if(!head||!head->next) return 0;
        ListNode* first = head, *second = head;
        while(first&&second){
            first = first->next;
            second = second->next;
            if(second) second = second->next;
            else return 0;
            if(first == second){
                first = head;
                while(first!=second){
                    first = first->next;
                    second = second->next;
                }
                return first;
            }
            
        }
        return 0;
    }
};

剑指offer 面试题 链表中倒数第k个节点

class Solution {
public:
    ListNode* findKthToTail(ListNode* head, int k) {
        int n = 0;
        for(auto p = head; p; p=p->next) n++;
        if(n<k) return nullptr;
        auto p = head;
        for(int i = 1; i < n-k+1; i++) p = p->next;
        return p;
    }
};

剑指offer 面试题 分行从上往下打印二叉树

class Solution {
public:
    vector<vector<int>> printFromTopToBottom(TreeNode* root) {
        vector<vector<int>> res;
        if(!root) return res;
        vector<int> level;
        queue<TreeNode*> q;
        q.push(root);
        q.push(nullptr);
        while(q.size()){
            TreeNode* t = q.front();
            q.pop();
            if(!t){
                if(level.empty()) break;
                res.push_back(level);
                level.clear();
                q.push(nullptr);
                continue;  
            }
            level.push_back(t->val);
            if(t->left) q.push(t->left);
            if(t->right) q.push(t->right);
        }
        return res;
    }
};
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

知行SUN

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值