文章目录
数值的整数次方
题目描述:
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
保证base和exponent不同时为0
class Solution {
public:
double quickMulti(double base, int exponent)
{
if(exponent == 1)
return base;
if(exponent == 0)
return 1.0;
double ret = quickMulti(base, exponent / 2);
if(exponent & 0x1)
{
return ret * ret * base;
}
else
return ret * ret;
}
double Power(double base, int exponent) {
if(exponent < 0)
{
base = 1.0 / base;
exponent *= -1;
}
return quickMulti(base, exponent);
}
};
二叉搜索树与双向链表
题目描述:
输入一颗二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。
class Solution {
public:
TreeNode* dfs(TreeNode* root, TreeNode* head, TreeNode* cur)
{
if(!root)
return nullptr;
dfs(root->left, head, cur);
if(!head)
{
head = root;
}
else
{
cur->right = root;
root->left = cur;
}
cur = root;
dfs(root->right, head, cur);
return head;
}
TreeNode* Convert(TreeNode* pRootOfTree) {
if(!pRootOfTree)
return nullptr;
TreeNode* head = nullptr;
TreeNode* cur = nullptr;
dfs(pRootOfTree, head, cur);
return head;
}
};
字符串的排列
题目描述:
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则按字典序打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bca,cab和cba。
输入描述:
输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
class Solution{
public:
void dfs(string str, int pos, set<string>& st)
{
if(pos + 1 == str.size())
{
st.insert(str);
return;
}
for(int i = pos; i < st.size(); i++)
{
swap(str[i], str[pos]);
dfs(str, pos+1, st);
swap(str[i], str[pos]);
}
return;
}
vector<string> Permutation(string str)
{
if(str.empty())
return vector<string>();
set<string> st;
dfs(str, 0, st);
return vector<string>(st.begin(), st.end());
}
};
两个链表的第一个公共结点
题目描述
输入两个链表,找出它们的第一个公共节点。
class Solution{
public:
ListNode* getIntersectionNode(ListNode* headA, ListNode* headB){
if(!headA || !headB)
return nullptr;
ListNode* p1 = headA;
ListNode* p2 = headB;
while(p1 != p2)
{
p1 = p1 ? p1->next:headB;
p2 = p2 ? p2->next:headA;
}
return p1;
}
};
最小的K个数
题目描述:
给定一个数组,找出其中最小的K个数。例如数组元素是4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。如果K>数组的长度,那么返回一个空的数组。
//大顶堆方法
class Solution
{
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k)
{
if(input.empty() || k > input.size() || k == 0)
return vector<int>();
if(k == input.size())
return input;
priority_queue<int, vector<int>> pq;
for(int i = 0; i < input.size(); i++)
{
if(i < k)
{
pq.push(input[i]);
}
else
{
if(input[i] < pq.top())
{
pq.pop();
pq.push(input[i]);
}
}
}
vector<int> ans;
while(!pq.empty())
{
ans.push_back(pq.top());
pq.pop();
}
return ans;
}
};
//快速排序+二分法
class Solution{
public:
int quickSort(vector<int>& input, int left, int right)
{
if(left < right)
{
while(left < right)
{
int x = input[left];
while(left < right && input[right] >= x)
right--;
if(left < right)
std::swap(input[left++],input[right]);
while(left < right && input[left] < x)
left++;
if(left < right)
std::swap(input[left], input[right--]);
}
input[left] = x;
return left;
}
return left;
}
vector<int> GetLeastNumbers_Solution(vector<int> input, int k){
if(input.empty() || k > input.size() || k == 0)
return vector<int>();
if(k == input.size())
return input;
int left = 0;
int right = input.size() - 1;
while(left < right)
{
int p = quickSort(input, left, right);
if(p+1 == k)
return vector<int>(input.begin(), input.begin() + k);
if(p+1 < k)
left = p+1;
else
right = p;
}
return vector<int>();
}
};
把数组排成最小的数
题目描述:
输入一个正整数数组,把数组里的所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
class Solution{
public:
string PrintMinNumber(vector<int> numbers){
vector<string> temp;
for(int i = 0; i < numbers.size(); i++)
temp.push_back(to_string(numbers[i]));
sort(temp.begin(), temp.end(), [](string a,string b){ return a+b<b+a; });
string ans;
for(int i = 0;i<numbers.size();i++)
ans += temp[i];
return ans;
}
}
数组的逆序对
题目描述:
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。即输出P%1000000007。
输入
[1,2,3,4,5,6,7,0]
输出
7
//归并排序
class Solution {
const int flag = 1000000007;
public:
void merge(vector<int>& data, int left, int mid, int right, int& ans)
{
vector<int> temp(right-left+1);
int i = left, j = mid+1;
int k = 0;
while(i <= mid && j <= right)
{
if(data[i] < data[j])
temp[k++] = data[i++];
else{
temp[k++] = data[j++];
ans += (mid - i + 1);
ans = ans % flag;
}
}
while(i <= mid)
{
temp[k++] = data[i++];
}
while(j <= right)
{
temp[k++] = data[j++];
}
for(int i = left, j = 0; j < k; j++, i++)
{
data[i] = temp[j];
}
return;
}
void mergeSort(vector<int>& data, int left, int right, int& ans)
{
if(left >= right)
return;
int mid = left + (right - left) / 2;
mergeSort(data, left, mid, ans);
mergeSort(data, mid+1, right, ans);
merge(data, left, mid, right, ans);
return;
}
int InversePairs(vector<int> data) {
if(data.empty())
return 0;
int ans = 0;
mergeSort(data, 0, data.size() - 1, ans);
return ans;
}
};
丑数
//包含质因子2,3,5的数称为丑数
//所以任何数乘以2,3,5的结果都是丑数
//第一个丑数是1,要求第index个
//所以就从1开始一直乘2,3,5,然后排序求出第index个数即可
//因为每次的乘积大小都不同,所以用三个变量分别标记每次乘积最小的那个
class Solution {
public:
int GetUglyNumber_Solution(int index) {
if(index <= 0)
return 0;
vector<int> dp(index);
int a = 0;
int b = 0;
int c = 0;
dp[0] = 1;
for(int i = 1; i < index; i++)
{
int n1 = dp[a] * 2;
int n2 = dp[b] * 3;
int n3 = dp[c] * 5;
dp[i] = min(min(n1, n2), n3);
if(dp[i] == n1)
a++;
if(dp[i] == n2)
b++;
if(dp[i] == n3)
c++;
}
return dp[index-1];
}
};
孩子们的游戏
//用temp记录下一次开始的位置
//(m-1)%n是前进的位置
//加上(temp)%n是该开始的位置
class Solution {
public:
int LastRemaining_Solution(int n, int m) {
if(m <= 0 || n <= 0)
return -1;
int temp = 0;
vector<int> vc;
for(int i = 0; i < n; i++)
vc.push_back(i);
while(n > 1)
{
temp = (temp + m - 1) % n;
auto be = vc.begin();
std::advance(be, temp);
vc.erase(be);
n--;
}
return vc[0];
}
};
把字符串转换成整数
class Solution {
public:
int StrToInt(string str) {
int len = str.size();
if(len == 0)
return 0;
int index = 0;
if(!isdigit(str[index]) && str[index] != '+' && str[index] != '-')
return 0;
long long ans = 0;
bool neg = str[index] == '-' ? true : false;
index = isdigit(str[index]) ? index : index+1;
while(index < len && isdigit(str[index]))
{
ans = ans * 10 + (str[index++] - '0');
if(!neg && ans >= INT_MAX)
{
ans = INT_MAX;
break;
}
else if(neg && ans >= INT_MAX + 1L)
{
ans = INT_MAX + 1L;
break;
}
}
if(index != len)
return 0;
return !neg ? static_cast<int>(ans) : static_cast<int>(-ans);
}
};
链表中环的入口节点
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead) {
if(!pHead)
return nullptr;
ListNode* fast = pHead;
ListNode* slow = pHead;
while(fast && fast->next)
{
fast = fast->next->next;
slow = slow->next;
if(slow == fast)
break;
}
if(!fast || !fast->next)
return nullptr;
fast = pHead;
while(fast != slow)
{
fast = fast->next;
slow = slow->next;
}
return fast;
}
};
构建乘积数组
//首先从左往右计算
//B[i]一开始表示在i位置左边(不包括i位置)的乘积
//然后从右往左计算
//B[i]表示在i位置右边(不包括i位置)的乘积
class Solution {
public:
vector<int> multiply(const vector<int>& A) {
vector<int> B(A.size(), 1);
for(int i = 1; i < A.size(); i++)
{
B[i] = A[i-1] * B[i-1];
}
int temp = 1;
for(int i = A.size() - 2; i >= 0; i--)
{
temp = temp * A[i+1];
B[i] = B[i] * temp;
}
return B;
}
};
滑动窗口的最大值
class Solution {
public:
vector<int> maxInWindows(const vector<int>& num, unsigned int size) {
if(size > num.size())
return vector<int>();
vector<int> ans;
deque<int> dq;
for(int i = 0; i < num.size(); i++)
{
while(!dq.empty() && num[i] > num[dq.back()])
dq.pop_back();
dq.push_back(i);
if(!dq.empty() && i - dq.front() > size -1)
dq.pop_front();
if(i >= size - 1)
ans.push_back(num[dq.front()]);
}
return ans;
}
};
剪绳子
class Solution {
public:
int cutRope(int number, vector<int>& mark)
{
if(number <= 4)
return number;
if(mark[number] != -1)
return mark[number];
int ret = 0;
for(int i = 1; i < number; i++)
{
ret = max(ret, i * cutRope(number-i, mark));
}
mark[number] = ret;
return ret;
}
int cutRope(int number) {
if(number == 2)
return 1;
if(number == 3)
return 2;
if(number == 4)
return 4;
vector<int> mark(number+1, -1);
return cutRope(number, mark);
}
};
正则表达式匹配
class Solution {
public:
bool match(string str, string pattern) {
// write code here
if(pattern.empty())
return str.empty();
int row = str.size();
int col = pattern.size();
vector<vector<int>> dp(row+1, vector<int>(col+1, false));
dp[0][0] = true;
for(int i = 2; i <= col; i++)
if(pattern[i-1] == '*')
dp[0][i] = dp[0][i-2];
for(int i = 1; i <= row; i++)
{
for(int j = 1; j <= col; j++)
{
if(str[i-1] == pattern[j-1] || pattern[j-1] == '.')
dp[i][j] = dp[i-1][j-1];
else if(pattern[j-1] == '*' && j >= 2)
{
if(pattern[j-2] != str[i-1] && pattern[j-2] != '.')
dp[i][j] = dp[i][j-2];
else
{
dp[i][j] = dp[i][j-2] || dp[i-1][j];
}
}
}
}
return dp[row][col];
}
};
序列化二叉树
//层次遍历
//atoi()函数的参数是const char*,对于一个字符串必须用c_str()函数把string转换成const char*
//
class Solution {
public:
char* Serialize(TreeNode *root) {
string str;
queue<TreeNode*> q;
q.push(root);
while(!q.empty())
{
TreeNode* temp = q.front();
q.pop();
if(!temp)
{
str += '#';
str += ',';
}
else
{
str += to_string(temp->val);
str += ',';
q.push(temp->left);
q.push(temp->right);
}
}
char* ch = new char[str.size() + 1];
strcpy(ch, str.c_str());
return ch;
}
TreeNode* Deserialize(char *str) {
if(!str)
return nullptr;
string str1(str);
if(str1[0] == '#')
return nullptr;
TreeNode* root = new TreeNode(atoi(str1.c_str()));
queue<TreeNode*> q;
q.push(root);
str1 = str1.substr(str1.find_first_of(',') + 1);
while(!q.empty() && !str1.empty())
{
TreeNode* temp = q.front();
q.pop();
if(str1[0] == '#')
{
temp->left = nullptr;
str1 = str1.substr(2);
}
else
{
temp->left = new TreeNode(atoi(str1.c_str()));
str1 = str1.substr(str1.find_first_of(',') + 1);
q.push(temp->left);
}
if(str1[0] == '#')
{
temp->right = nullptr;
str1 = str1.substr(2);
}
else
{
temp->right = new TreeNode(atoi(str1.c_str()));
str1 = str1.substr(str1.find_first_of(',') + 1);
q.push(temp->right);
}
}
return root;
}
};