class Solution {
public:
int jumpFloorII(int number)
{
return 1<<(number-1);
}
};
题目:变态跳台阶
题目讲解:https://www.nowcoder.com/questionTerminal/22243d016f6b47f2a6928b4313c85387
题目:最小的K个数问题
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k)
{
vector<int> result;
priority_queue<int, vector<int>, greater<int> > q;//greater<>是仿函数,用于申明小根堆
int size = input.size();
if(size < k) result;
for(int i=0;i<size;++i)
{
q.push(input[i]);
}
for(int i=0;i<k;++i)
{
result.push_back(q.top());
q.pop();
}
return result;
}
};
本题还有个最优解:利用bfprt算法
题目 4:替换空格
解法1:用了额外空间的O(N)算法
class Solution {
public:
void replaceSpace(char *str,int length)
{
string s;
char *p = str;
while(*p != '\0')
{
if(*p != ' ')
s += *p;
else s += "%20";
p++;
}
int i = 0;
for(; i<s.size(); ++i)
{
str[i] = s[i];
}
str[i] = '\0';
}
};
解法2:不用额外空间的O(N) 的算法
class Solution {
public:
void replaceSpace(char *str,int length)
{
int size = 0;
if(str == NULL || length <=0)
return ;
int count = 0;
while(str[size] != '\0')
{
if(str[size] == ' ') count ++;
size++;
}
--size;
int newLen = size + 2*count;
if(newLen > length) return ;
int indexOne = size;
int indexTwo = newLen;
while(indexOne>=0 && indexOne<indexTwo)
{
if(str[indexOne] == ' ')
{
str[indexTwo --] = '0';
str[indexTwo --] = '2';
str[indexTwo --] = '%';
}
else
{
str[indexTwo --] =str[indexOne];
}
--indexOne;
}
}
};
题目5:从尾到头打印链表
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head)
{
stack<int> myStack;
vector<int> result;
ListNode* n = head ;
if(n == NULL)
return result;
while(n)
{
myStack.push(n->val);
n = n->next;
}
while(!myStack.empty())
{
result.push_back(myStack.top());
myStack.pop();
}
return result;
}
};
经典的栈(递归)结构
面试题7:用两个栈实现队列
class Solution
{
public:
void push(int node)
{
stack1.push(node);
}
int pop()
{
if(stack2.empty())
{
while(!stack1.empty())
{
stack2.push(stack1.top());
stack1.pop();
}
}
if(stack2.empty()) return -1;
else
{
int result = stack2.top();
stack2.pop();
return result;
}
}
private:
stack<int> stack1;
stack<int> stack2;
};
leetcode:33. 搜索旋转排序数组
class Solution {
public:
int fun(vector<int>& nums,int target,int begin,int end)
{
if(begin < 0 || end >=nums.size())
return -1;
int midan;
if(nums[begin] == target) return begin;
else if(nums[end] == target) return end;
while(begin < end)
{
midan = (end+begin)/2;
if(nums[midan] == target) return midan;
else if(nums[midan] < target)
begin = midan+1;
else if(nums[midan] > target)
end = midan-1;
}
if(begin == end && nums[begin] == target) return begin;
else return -1;
}
int search(vector<int>& nums, int target)
{
int size = nums.size();
if(size == 0) return -1;
int indexLeft = 0;
int indexRight = size-1;
int indexMidan = indexLeft;
int indexMin;
while(nums[indexLeft] > nums[indexRight])
{
indexMidan = (indexRight + indexLeft)/2;
if(indexLeft+1 == indexRight)
break;
if(nums[indexLeft] < nums[indexMidan])//中点在左边数组,最小值在右边,不会是自己
indexLeft = indexMidan;
else if(nums[indexLeft] > nums[indexMidan])//中点在右边数组,最小值在左边,也可能是自己
indexRight = indexMidan;
}
indexMin = indexRight;
if(indexMin == 0)
return fun(nums,target,0,size-1);
else if(target <= nums[size-1] && target >= nums[indexMin])
return fun(nums,target,indexMin,size-1);
else if(target >=nums[0] && target <=nums[indexMin-1])
return fun(nums,target,0,indexMin-1);
return -1;
}
};
leetcode:74. 搜索二维矩阵
log n + log m
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target)
{
int hang = matrix.size();
if(hang == 0) return false;
int lie = matrix[0].size();
if(lie == 0) return false;
int left = 0;
int right = hang-1;
int k = 0;
int midan;
while(left+1<right)
{
midan = (left+right) / 2;
if(matrix[left][lie-1] > target)
{
k=left;
break;
}
else if(matrix[left][lie-1] == target)
return true;
else if(matrix[left][lie-1] < target)
{
if(matrix[midan][lie-1] < target)
left = midan;
else if(matrix[midan][lie-1] == target)
return true;
else if(matrix[midan][lie-1] > target)
right = midan;
}
}
if(matrix[left][lie-1] < target)
k=right;
left = 0;right=lie-1;
while(left<right)
{
midan = (left+right) / 2;
if(matrix[k][midan] == target) return true;
else if(matrix[k][midan] < target) left = midan+1;
else right = midan-1;
}
if(left == right && matrix[k][left] == target) return true;
else return false;
}
};
leetcode:191. 位1的个数
class Solution {
public:
int hammingWeight(uint32_t n)
{
int result = 0;
while(n)
{
n &= (n-1);
++result;
}
return result;
}
};
leetcode:136. 只出现一次的数字
class Solution {
public:
int singleNumber(vector<int>& nums)
{
int result=nums[0];
int size = nums.size();
for(int i=1;i<size;++i)
result ^= nums[i];
return result;
}
};
leetcode:62. 不同路径
class Solution {
public:
int uniquePaths(int m, int n)
{
int** arr = new int*[m];
for(int i=0;i<m;++i)
arr[i] = new int[n];
for(int i=0;i<m;++i)
arr[i][0] = 1;
for(int i=0;i<n;++i)
arr[0][i] = 1;
for(int i=1;i<m;++i)
{
for(int j=1;j<n;++j)
{
arr[i][j] = arr[i-1][j] + arr[i][j-1];
}
}
return arr[m-1][n-1];
}
};
leetcode:392. 判断子序列
class Solution {
public:
bool isSubsequence(string s, string t)
{
int ssize = s.size();
int tsize = t.size();
int j=0;
for(int i=0;i<tsize;++i)
{
if(j == ssize) return true;
if(t[i] == s[j]) ++j;
}
if(j == ssize) return true;
return false;
}
};
leetcode:922. 按奇偶排序数组 II
class Solution {
public:
vector<int> sortArrayByParityII(vector<int>& arr)
{
int size = arr.size();
if(size == 0 && size == 1) return arr;
int left = 1;
int right = size - 2;
while(left<size && right>=0)
{
while(left<size && (arr[left]&1) == 1)
left+=2;
while(right>=0 && (arr[right]&1) == 0)
right-=2;
if(left<size && right>=0)
swap(arr[left],arr[right]);
}
return arr;
}
};
剑指offer:反转链表
class Solution {
public:
ListNode* ReverseList(ListNode* pHead)
{
if(pHead == NULL)
return NULL;
ListNode* left = NULL;
ListNode* right = pHead;
ListNode* m = NULL;
while(right)
{
left = m;
m = right ;
right = right->next;
m->next = left;
}
return m;
/* if(pHead == NULL)
return NULL;
ListNode* p = pHead;
stack<ListNode*> myStack;
while(p->next)
{
myStack.push(p);
}
pHead = p;
while(!myStack.empty())
{
p->next = myStack.top();
p = p->next;
myStack.pop();
}
return pHead;*/
}
};
剑指offer:倒数第k个链表节点
class Solution {
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k)
{
if(pListHead == NULL)
return NULL;
ListNode* left = pListHead;
ListNode* right = left;
for(int i=0;i<k-1;++i)
{
if(right->next == NULL)
return NULL;
right = right->next;
}
while(right->next)
{
left = left->next;
right = right->next;
}
return left;
}
};
剑指offer:合并有序链表
class Solution {
public:
ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
{
if(pHead1 == NULL)
return pHead2;
else if(pHead2 == NULL)
return pHead1;
if(pHead1->val < pHead2->val)
{
pHead1->next = Merge(pHead1->next,pHead2);
return pHead1;
}
else if(pHead1->val >= pHead2->val)
{
pHead2->next = Merge(pHead1,pHead2->next);
return pHead2;
}
else return NULL;
}
};
剑指offer:第一个只出现一次的字符
class Solution {
public:
int FirstNotRepeatingChar(string str)
{
map<char,int> m;
int arr[52];
int size = str.size();
if(size == 0) return -1;
for(int i=0;i<size;++i)
{
map<char,int>::iterator it = m.find(str[i]);
if(it == m.end())
m.insert(pair<char,int>(str[i],1));
else it->second++;
}
for(int i=0;i<size;++i)
{
map<char,int>::iterator it = m.find(str[i]);
if(it == m.end()) continue;
if(it->second == 1) return i;
}
return -1;
}
};
剑指offer:包含min函数的栈
class Solution {
public:
stack<int> myStack, minStack;
void push(int value)
{
myStack.push(value);
if(minStack.empty()) minStack.push(value);
else
{
int tim = minStack.top();
if(tim <= value) minStack.push(tim);
else minStack.push(value);
}
}
void pop()
{
if(myStack.empty())
return;
myStack.pop();
minStack.pop();
}
int top()
{
if(myStack.empty()) return -1;
return myStack.top();
}
int min()
{
if(minStack.empty())
return -1;
return minStack.top();
}
};
剑指offer:数组中只出现一次的数字
class Solution {
public:
void FindNumsAppearOnce(vector<int> data,int* num1,int *num2)
{
vector<int> nums1;
vector<int> nums2;
int size = data.size();
if(size < 2) return ;
int tim = data[0];
for(int i=1;i<size;++i)
{
tim^=data[i];
}
int re = 1;
while((tim&re) == 0) re = (re << 1);
for(int i=0;i<size;++i)
{
if((data[i]&re) == 0)nums1.push_back(data[i]);
else nums2.push_back(data[i]);
}
int result1 = nums1[0];
for(int i=1;i<nums1.size();++i)
result1^=nums1[i];
int result2 = nums2[0];
for(int i=1;i<nums2.size();++i)
result2^=nums2[i];
*num1 = result1;
*num2 = result2;
}
};
leetcode:3. 无重复字符的最长子串
class Solution {
public:
int lengthOfLongestSubstring(string s)
{
map<char,int> m;
int result = 0;
int size = s.size();
int left = 0;
map<char,int>::iterator it;
for(int i=0;i<size;++i)
{
it = m.find(s[i]);
if(it == m.end())
{
m.insert({s[i],i});
}
else
{
left = it->second<left?left:(it->second+1);
it->second = i;
}
result = result<(i-left+1)?(i-left+1):result;
}
return result;
}
};
剑指offer:树的子结构
class Solution {
public:
bool fun(TreeNode* p1,TreeNode* p2)
{
if(p2 == NULL) return true;
if(p1 == NULL) return false;
if(p1->val == p2->val)
return fun(p1->left,p2->left) && fun(p1->right,p2->right);
return false;
}
bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
{
bool flag = false;
if(pRoot1 == NULL || pRoot2 == NULL)
return false;
if(pRoot1->val == pRoot2->val)
{
flag = fun(pRoot1,pRoot2);
}
if(flag == false)
{
flag = HasSubtree(pRoot1->left,pRoot2);
}
if(flag == false)
{
flag = HasSubtree(pRoot1->right,pRoot2);
}
return flag;
}
};
剑指offer:二叉树的镜像
class Solution {
public:
void Mirror(TreeNode *pRoot)
{
if(pRoot == NULL) return;
TreeNode* tim = pRoot->left;
pRoot->left = pRoot->right;
pRoot->right = tim;
Mirror(pRoot->right);
Mirror(pRoot->left);
}
};
剑指offer:栈的压入,弹出序列
class Solution {
public:
bool IsPopOrder(vector<int> pushV,vector<int> popV)
{
int size1 = pushV.size();
int size2 = popV.size();
stack<int> myStack;
int i = 0;
int j = 0;
while(i < size2)
{
if(myStack.empty()) myStack.push(pushV[j++]);
if(popV[i] == myStack.top())
{
myStack.pop();
++i;
}
else if(j < size1)
{
myStack.push(pushV[j++]);
}
else
{
return false;
}
}
if(myStack.empty() && j == size1 && i==size2) return true;
else return false;
}
};
剑指offer:从上往下打印二叉树(层次遍历)
class Solution {
public:
vector<int> PrintFromTopToBottom(TreeNode* root)
{
vector<int> result;
if(root == NULL) return result;
queue<TreeNode*> myQueue;
myQueue.push(root);
TreeNode *tim;
while(!myQueue.empty())
{
tim = myQueue.front();
result.push_back(tim->val);
if(tim->left != NULL) myQueue.push(tim->left);
if(tim->right != NULL) myQueue.push(tim->right);
myQueue.pop();
}
return result;
}
};
剑指offer:二叉搜索树的后序遍历序列
class Solution {
public:
bool fun(vector<int>& v,int begin,int end)
{
int size = v.size();
if(begin < 0 || end >= size)
{
return false;
}
if(begin == end) return true;
int root = end;
int right = begin;
for(int i = begin;i<end;++i)
{
if(v[i] < v[root]) right = i+1;
else
{
break;
}
}
for(int i = right;i<end;++i)
{
if(v[i] < v[root]) return false;
}
if(right == begin)
{
return fun(v,begin,end - 1);
}
if(right == end)
{
return fun(v,begin,end - 1);
}
return fun(v,begin,right-1) && fun(v,right,end-1);
}
bool VerifySquenceOfBST(vector<int> sequence)
{
return fun(sequence, 0, sequence.size()-1);
}
};
leetcode:55.跳跃游戏
class Solution {
public:
bool fun(vector<int>& nums, int index)
{
int size = nums.size();
if(size == 0) return false;
if(index == size-1) return true;
else if(index > size-1) return false;
bool result = false;
for(int i=1;i<=nums[index];++i)
{
result |= fun(nums,index+i);
}
return result;
}
bool canJump(vector<int>& nums)
{
return fun(nums,0);
}
};
递归版本,leetcode上超时。
贪心版本
class Solution {
public:
bool canJump(vector<int>& nums)
{
int size = nums.size();
int max = 0;
for(int i=0;i<size;++i)
{
if(max < i) return false;
max = max>(nums[i]+i)?max:(nums[i]+i);
}
return true;
}
};
leetcode:23. 合并K个排序链表
class Solution {
public:
template<class _Ty = void>
struct greater1
{
constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const
{
return (_Left->val > _Right->val);
}
};
ListNode* mergeKLists(vector<ListNode*>& lists)
{
int size = lists.size();
if(size == 0) return NULL;
ListNode* result = NULL;
ListNode* p = NULL;
priority_queue<ListNode*, vector<ListNode*>, greater1<ListNode*>> test;
for(int i=0;i<size;++i)
{
if(lists[i] != NULL)
test.push(lists[i]);
}
while(!test.empty())
{
ListNode* top = test.top();
test.pop();
if(result == NULL)
{
result = top;
p = top;
}
else
{
p->next = top;
p = p->next;
}
if(top != NULL && top->next != NULL)
{
test.push(top->next);
}
}
return result;
}
};
剑指offer:二叉树中和为某一值的路径
class Solution {
public:
vector<vector<int>> result;
void Find(TreeNode* root,int expectNumber,int preSum,vector<int>& myStack)
{
if(root == NULL) return ;
preSum+=root->val;
myStack.push_back(root->val);
if(root != NULL && preSum == expectNumber && root->left == NULL && root->right == NULL)
{
result.push_back(myStack);
myStack.pop_back();
return ;
}
Find(root->left,expectNumber,preSum,myStack);
Find(root->right,expectNumber,preSum,myStack);
myStack.pop_back();
}
vector<vector<int>> FindPath(TreeNode* root,int expectNumber)
{
if(root == NULL)
return result;
vector<int> myStack;
Find(root,expectNumber,0,myStack);
return result;
}
};
剑指offer:数组中的逆序对
class Solution {
public:
long mergeSort(vector<int>& nums, int begin, int end)
{
long result = 0;
int size = nums.size();
if(size == 0 || begin < 0 || end >= size)
return 0;
if(begin == end) return 0 ;
int mid = (end + begin) >> 1;
result += mergeSort(nums, begin, mid);
result += mergeSort(nums, mid+1, end);
vector<int> tim;
int i = begin;
int j = mid+1;
while(i <= mid && j<=end)
{
if(nums[i] < nums[j])
{
tim.push_back(nums[i++]);
}
else
{
result += (mid-i+1);
tim.push_back(nums[j++]);
}
}
while(i<=mid)
{
tim.push_back(nums[i++]);
}
while(j<=end)
{
tim.push_back(nums[j++]);
}
for(int k = 0;k<tim.size();++k)
{
nums[begin + k] = tim[k];
}
return result;
}
int InversePairs(vector<int> data)
{
return mergeSort(data,0,data.size()-1)%1000000007;
}
};
剑指offer:连续子数组的最大和
class Solution {
public:
int FindGreatestSumOfSubArray(vector<int> array)
{
int size = array.size();
if(size == 0) return 0;
int maxResult = array[0];
int tim = 0;
for(int i=0;i<size;++i)
{
tim+=array[i];
maxResult = maxResult < tim?tim:maxResult;
if(tim < 0) tim = 0;
}
return maxResult;
}
};
剑指offer:最小的k个数
class Solution {
public:
int partition(vector<int>& nums,int begin, int end)
{
int size = nums.size();
if(size == 0 || begin < 0 || end >= size || end < begin)
return -1;
int index = (rand() % (end-begin+1))+ begin;
int small = begin - 1;
swap(nums[index],nums[end]);
for(int i=begin;i<end;++i)
{
if(nums[i] < nums[end])
{
++small;
if(small != i) swap(nums[i],nums[small]);
}
}
++small;
swap(nums[small], nums[end]);
return small;
}
vector<int> GetLeastNumbers_Solution(vector<int> input, int k)
{
int size = input.size();
vector<int> result;
if (size == 0) return result;
if (k == size)
{
return input;
}
else if (k > size) return result;
int begin = 0; int end = size - 1;
int index = partition(input, begin, end);
while (index != k)
{
if (index == -1) return result;
else if (index < k)
{
begin = index + 1;
}
else if (index > k)
{
end = index - 1;
}
index = partition(input, begin, end);
}
int K = 0;
for (int i = 0; i < size; ++i)
{
if (input[i] < input[index])
{
result.push_back(input[i]);
++K;
}
}
for (; K < k; ++K)
{
result.push_back(input[index]);
}
return result;
}
};
剑指offer:数组中出现次数超过一半的数
class Solution {
public:
int partition(vector<int> nums,int begin, int end)
{
int size = nums.size();
if(size == 0 || begin <0 || end >= size)
return -1;
int index = (rand() % (end-begin+1))+ begin;
swap(nums[index],nums[end]);
int small = begin - 1;
for(int i=begin;i<end;++i)
{
if(nums[i] < nums[end])
{
++small;
if(small != i) swap(nums[small],nums[i]);
}
}
++small;
swap(nums[small],nums[end]);
return small;
}
int MoreThanHalfNum_Solution(vector<int> numbers)
{
int size = numbers.size();
if(size == 0) return 0;
int mid = size >> 1;
int index = 0;
int begin = 0, end = size-1;
while(index != mid)
{
if(index < mid)
{
begin = index+1;
}
else if(index > mid)
{
end = index-1;
}
index = partition(numbers,begin,end);
}
int count = 0;
for(int i=0;i<size;++i)
{
if(numbers[i] == numbers[index]) ++count;
}
if(count > mid) return numbers[index];
else return 0;
}
};
剑指offer:两个链表的第一个公共节点
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2)
{
ListNode* result = NULL;
if(pHead1 == NULL || pHead2 == NULL) return result;
stack<ListNode*> s1,s2;
ListNode* p = pHead1;
while(p)
{
s1.push(p);
p = p->next;
}
p = pHead2;
while(p)
{
s2.push(p);
p = p->next;
}
while(!s1.empty() && !s2.empty())
{
if(s1.top() == s2.top())
{
result = s1.top();
s1.pop();
s2.pop();
}
else
{
return result;
}
}
return result;
}
};
剑指offer:和为s的两个数字
class Solution {
public:
vector<int> FindNumbersWithSum(vector<int> array,int sum)
{
vector<int> result;
int size = array.size();
if(size<2) return result;
map<int, int> m;
for(int i=0;i<size;++i)
{
m.insert({array[i],i});
}
int tim, min = 0x7fffffff;
for(int i=0;i<size;++i)
{
map<int, int>::iterator it = m.find(sum - array[i]);
if(it != m.end() && it->second != i)
{
tim = array[i]*(it->first);
if(tim < min)
{
min = tim;
result.clear();
result.push_back(array[i]);
result.push_back(it->first);
}
}
}
return result;
}
};
剑指offer:二叉树的深度
class Solution {
public:
int treeDepth(TreeNode* root, int preDepth)
{
if(root == NULL) return preDepth;
int left, right;
left = treeDepth(root->left,preDepth+1);
right = treeDepth(root->right,preDepth+1);
return left>right?left:right;
}
int TreeDepth(TreeNode* pRoot)
{
return treeDepth(pRoot, 0);
}
};
剑指offer:左旋转字符串
class Solution {
public:
string LeftRotateString(string str, int n)
{
int size = str.size();
if(size <= 1) return str;
n %= size;
string s1 = "";
string s2 = "";
for(int i = 0;i<n;++i)
{
s1 += str[i];
}
for(int i = n;i<size;++i)
{
s2 += str[i];
}
return s2+s1;
}
};
剑指offer:翻转单词顺序列
class Solution {
public:
string ReverseSentence(string str)
{
string s;
map<int, string> m;
int size = str.size();
if(size == 0) return s;
int count = 0;
string k = " ";
for(int i=0;i<size;++i)
{
string tim;tim += str[i];
if((k == tim) && (!s.empty()))
{
m.insert({count++,s});
s.clear();
}
else
{
s += str[i];
}
}
if(!s.empty())
{
m.insert({count++,s});
s.clear();
}
string result;
for(int i=count-1;i>=0;--i)
{
map<int, string>::iterator it = m.find(i);
if(it != m.end())
{
if(i != 0)
result += it->second + " ";
else
result += it->second;
}
}
return result;
}
};
剑指offer:滑动窗口的最大值
class Solution {
public:
vector<int> maxInWindows(const vector<int>& num, unsigned int size)
{
deque<int> q;
vector<int> result;
int nsize = num.size();
if(nsize == 0 || size == 0) return result;
for(int i=0;i<nsize;++i)
{
if(q.empty()) q.push_back(i);
while(!q.empty() && num[q.back()] <= num[i])
{
q.pop_back();
}
q.push_back(i);
if(q.front() == i-size) q.pop_front();
if(i >= size-1) result.push_back(num[q.front()]);
}
return result;
}
};
剑指offer:平衡二叉树
class Solution {
public:
bool fun(TreeNode* root, int& preD)
{
if(root == NULL)
{
preD = 0;
return true;
}
int left,right;
bool result = true;
result &= fun(root->left,left);
result &= fun(root->right,right);
preD = left>right?left+1:right+1;
if(abs(left - right) > 1) return false;
else return result;
}
bool IsBalanced_Solution(TreeNode* pRoot)
{
int i = 0;
return fun(pRoot,i);
}
};
剑指offer:和为s的连续正数序列
class Solution {
public:
vector<vector<int>> FindContinuousSequence(int sum)
{
vector<vector<int>> result;
if(sum < 3) return result;
int left = 1,right = 2;
int mid = sum/2+1;
int tmp = 3;
vector<int> v;
while(left<mid)
{
if(tmp<sum)
{
++right;
tmp+=right;
}
else if(tmp>sum)
{
tmp-=left;
++left;
}
else if(tmp == sum)
{
v.clear();
for(int i=left;i<=right;++i) v.push_back(i);
result.push_back(v);
}
}
return result;
}
};
剑指offer:不用加减乘除做加法
class Solution {
public:
int Add(int num1, int num2)
{
int n1, n2;
do
{
n1 = num1^num2;
n2 = (num1&num2)<<1;
num1 = n1;
num2 = n2;
}while(num2);
return num1;
}
};
剑指offer:圆圈最后剩下的数
class Solution {
public:
int LastRemaining_Solution(int n, int m)
{
if(n<1 || m<1) return -1;
if(n == 1) return 0;
return (LastRemaining_Solution(n-1,m)+m)%n;
}
};
判断一个数组中哪些可能是partition函数调用后枢纽值
https://pintia.cn/problem-sets/994805260223102976/problems/994805278589960192
vector<int> fun(vector<int> nums)
{
vector<int> result;
int size = nums.size();
if (size <= 1) return nums;
int leftMax = 0x80000000;
stack<int> s;
for (int i = size - 1; i > 0; --i)
{
if (s.empty()) s.push(nums[i]);
else if (s.top() > nums[i]) s.push(nums[i]);
else s.push(s.top());
}
for (int i = 0; i < size; ++i)
{
if (nums[i] >= leftMax && (s.empty() || nums[i] <= s.top()))
{
result.push_back(nums[i]);
leftMax = nums[i];
}
else
{
leftMax = leftMax < nums[i] ? nums[i] : leftMax;
}
if(!s.empty()) s.pop();
}
return result;
}
剑指offer:数据流中的中位数
class Solution {
public:
priority_queue<int,vector<int>,greater<int>> min;
priority_queue<int> max;
void Insert(int num)
{
int tim = num;
if (((min.size() + max.size()) & 1) == 0)//偶数
{
if (!max.empty() && num < max.top())
{
max.push(num);
tim = max.top();
max.pop();
}
min.push(tim);
}
else
{
if (!min.empty() && num > min.top())
{
min.push(num);
tim = min.top();
min.pop();
}
max.push(tim);
}
}
double GetMedian()
{
int size = min.size() + max.size();
if((size & 1) == 1) return (double)min.top();
else return ((double)max.top() + (double)min.top()) / 2;
}
};
leetcode:1005. K 次取反后最大化的数组和
class Solution {
public:
int largestSumAfterKNegations(vector<int>& A, int K)
{
priority_queue<int,vector<int>,greater<int>> q;
int size = A.size();
if(size == 0) return 0;
for(int i=0;i<size;++i)
{
q.push(A[i]);
}
while(K)
{
int tim = -1*q.top();
q.pop();
q.push(tim);
K--;
}
int result = 0;
while(!q.empty())
{
result += q.top();
q.pop();
}
return result;
}
};
leetcode:1007. 行相等的最少多米诺旋转
class Solution {
public:
int find(int* arr,int size,int length)
{
int result = 0;
int max = arr[0];
for(int i=0;i<size;++i)
{
if(arr[i] >= max)
{
//if(arr[i] == length) return -1;
result = i;
max = arr[i];
}
}
return result;
}
int minDominoRotations(vector<int>& A, vector<int>& B)
{
int leftMin = -1, rightMin = -1;
int size = A.size();
int arrA[7] = { 0,0,0,0,0,0,0 }, arrB[7] = { 0,0,0,0,0,0,0 };
for (int i = 0; i < size; ++i)
{
arrA[A[i]]++;
arrB[B[i]]++;
}
for (int i = 0; i < 6; ++i)
{
int j;
int tim = find(arrA, 7, size);
//if (tim == -1) return 0;
for (j = 0; j < size; ++j)
{
if (A[j] != tim && B[j] != tim)
{
break;
}
}
if (j == size)
{
leftMin = size - arrA[tim];
break;
}
arrA[tim] = 0;
}
for (int i = 0; i < 6; ++i)
{
int j;
int tim = find(arrB, 7, size);
// if (tim == -1) return 0;
for (j = 0; j < size; ++j)
{
if (B[j] != tim && A[j] != tim)
{
break;
}
}
if (j == size)
{
rightMin = size - arrB[tim];
break;
}
arrB[tim] = 0;
}
if (leftMin != -1 && rightMin != -1)
return leftMin < rightMin ? leftMin : rightMin;
else if (leftMin == -1) return rightMin;
else return leftMin;
}
};
剑指offer:二叉树的下一个节点
class Solution {
public:
TreeLinkNode* GetNext(TreeLinkNode* root)
{
if(root == NULL) return NULL;
TreeLinkNode* r = root;
if(root->right != NULL)
{
TreeLinkNode* temp = root->right;
while(temp->left != NULL)
{
temp = temp->left;
}
return temp;
}
else
{
while(root->next != NULL)
{
if(root->next->left == root) return root->next;
else
{
root = root->next;
}
}
return NULL;
}
}
};
剑指offer:字符流中第一个不重复的字符
class Solution
{
public:
int arr[256];
int index;
Solution()
{
index = 0;
for(int i = 0;i<256;++i) arr[i] = -1;
}
//Insert one char from stringstream
void Insert(char ch)
{
int t = (int)ch;
if(arr[t] == -1) arr[t] = index;
else arr[t] = -2;
++index;
}
//return the first appearence once char in current stringstream
char FirstAppearingOnce()
{
int MinIndex = 0x7fffffff;
char result = '#';
for(int i=0;i<256;++i)
{
if(arr[i] >= 0 && MinIndex > arr[i])
{
MinIndex = arr[i];
result = (char)i;
}
}
return result;
}
};
剑指offer:链表中环的入口节点
class Solution {
public:
ListNode* MeetingNode(ListNode* head)
{
if(head == NULL) return NULL;
ListNode* slow = head->next;
if(slow == NULL) return NULL;
ListNode* fast = slow->next;
while(slow!=NULL && fast!=NULL)
{
if(slow == fast) return fast;
slow = slow->next;
fast = fast->next;
if(fast->next != NULL)
{
fast = fast->next;
}
else return NULL;
}
return NULL;
}
ListNode* EntryNodeOfLoop(ListNode* head)
{
if(head == NULL) return NULL;
ListNode* current = MeetingNode(head);
if(current == NULL) return NULL;
int count = 1;
ListNode* tim = current->next;
while(tim != current)
{
++count;
tim = tim->next;
}
ListNode* fast = head;
ListNode* slow = head;
while(count>0)
{
fast = fast->next;
--count;
}
while(slow != fast)
{
slow=slow->next;
fast=fast->next;
}
return fast;
}
};
leetcode:997. 找到小镇的法官
class Solution {
public:
int findJudge(int N, vector<vector<int>>& trust)
{
int re = 0;
int result = -1;
if(N == 1) return 1;
if(trust.empty()) return -1;
int *arr = new int[N+1];
for(int i=0;i<=N;++i) arr[i] = 0;
map<int,int>m;
map<int,int>::iterator it;
int size = trust.size();
for(int i=0;i<size;++i)
{
arr[trust[i][1]]++;
m.insert({trust[i][0],trust[i][1]});
}
for(int i=1;i<=N;++i)
{
if(arr[i] == N-1)
{
++re;
it = m.find(i);
if(it == m.end())
{
result = i;
}
}
}
return (re!=1)?-1:result;
}
};
leetcode:41. 缺失的第一个正数
class Solution {
public:
int firstMissingPositive(vector<int>& nums)
{
int size = nums.size();
if(size == 0) return 1;
for(int i=0;i<size;)
{
if(nums[i] != i+1)
{
if(nums[i]>0 && (nums[i] <= size) && nums[nums[i]-1] != nums[i])
{
swap(nums[i],nums[nums[i]-1]);
}
else ++i;
}
else ++i;
}
for(int i=0;i<size;++i)
{
if(nums[i] != i+1) return i+1;
}
return size+1;
}
};
剑指offer:二叉搜索树的第k个节点
class Solution {
public:
vector<TreeNode*> v;
void fun(TreeNode* root)
{
if(root == NULL) return;
fun(root->left);
v.push_back(root);
fun(root->right);
}
TreeNode* KthNode(TreeNode* root, int k)
{
if(k == 0 || root == NULL) return NULL;
fun(root);
if(k<=v.size()) return v[k-1];
else return NULL;
}
}
剑指offer:把二叉树打印成多行
class Solution {
public:
vector<vector<int> > Print(TreeNode* root)
{
queue<TreeNode*> q;
vector<vector<int>> result;
int current = 1;
int nexth = 0;
if(root == NULL) return result;
TreeNode* p = root;
q.push(p);
while(!q.empty())
{
vector<int> v;
while(current)
{
TreeNode* t = q.front();
v.push_back(t->val);
if(t->left != NULL)
{
q.push(t->left);
++nexth;
}
if(t->right != NULL)
{
q.push(t->right);
++nexth;
}
q.pop();
--current;
}
current = nexth;
nexth = 0;
result.push_back(v);
v.clear();
}
return result;
}
};
剑指offer:按之子型打印二叉树
class Solution {
public:
vector<vector<int> > Print(TreeNode* root)
{
vector<vector<int>> result;
if(root == NULL) return result;
stack<TreeNode*> qi;
stack<TreeNode*> ou;
qi.push(root);
int hang = 1;
vector<int> v;
while(!qi.empty() || !ou.empty())
{
if(hang&1)
{
v.clear();
while(!qi.empty())
{
TreeNode* tim = qi.top();
v.push_back(tim->val);
if(tim->left != NULL) ou.push(tim->left);
if(tim->right != NULL) ou.push(tim->right);
qi.pop();
}
++hang;
result.push_back(v);
}
else
{
v.clear();
while(!ou.empty())
{
TreeNode* tim = ou.top();
v.push_back(tim->val);
if(tim->right != NULL) qi.push(tim->right);
if(tim->left != NULL) qi.push(tim->left);
ou.pop();
}
++hang;
result.push_back(v);
}
}
return result;
}
};
剑指offer:对称的二叉树
class Solution {
public:
bool isSymmetrical(TreeNode* root1,TreeNode* root2)
{
if(root1==NULL && root2==NULL) return true;
if(root1==NULL || root2==NULL) return false;
if(root1->val == root2->val)
{
return isSymmetrical(root1->left,root2->right) && isSymmetrical(root1->right,root2->left);
}
return false;
}
bool isSymmetrical(TreeNode* root)
{
return isSymmetrical(root,root);
}
};
leetcode:
class Solution {
public:
int removeDuplicates(vector<int>& nums)
{
int size = nums.size();
if(size <= 1) return size;
int fast=1,slow=0;
while(fast<size)
{
if (nums[fast] != nums[slow]) nums[++slow] = nums[fast];
++fast;
}
return slow+1;
}
};
leetcode:
class Solution {
public:
int fun(vector<int>& nums, int target,int left, int right)
{
int size = nums.size();
if(size == 0) return -1;
if(left < 0 || right >=size) return -1;
int begin = left;
int end = right;
int midan;
while(begin <= end)
{
midan = (begin + end)/2;
if(nums[midan] == target) return midan;
if(nums[midan] < target) begin = midan+1;
else if(nums[midan] > target) end = midan-1;
}
return -1;
}
int search(vector<int>& nums, int target)
{
int size = nums.size();
if(size == 0) return -1;
else if(size == 1) return nums[0] == target?0:-1;
if(nums[0] < nums[size-1])
{
return fun(nums,target,0,size-1);
}
else
{
int midan;
int begin = 0,end = size-1;
while(begin < end-1)
{
midan = (begin+end)/2;
if(nums[midan] > nums[end]) begin = midan;
else if(nums[midan] < nums[begin]) end = midan;
}
int min = end;
int result = fun(nums,target,0,min-1);
if(result != -1) return result;
return fun(nums,target,min,size-1);
}
}
};
leetcode:80. 删除排序数组中的重复项 II
class Solution {
public:
int removeDuplicates(vector<int>& nums)
{
int size = nums.size();
if(size <= 2) return size;
int fast=1,slow=0;
int current = nums[slow];
int count = 1;
while(fast<size)
{
if(nums[fast] == current && count < 2)
{
++count;
nums[++slow] = nums[fast];
}
else if(nums[fast] != current)
{
count = 1;
current = nums[fast];
nums[++slow] = nums[fast];
}
//if (nums[fast] != nums[slow]) nums[++slow] = nums[fast];
++fast;
}
return slow+1;
}
};
leetcode:153. 寻找旋转排序数组中的最小值
class Solution {
public:
int findMin(vector<int>& nums)
{
int size = nums.size();
if(size == 0) return -1;
if(size == 1) return nums[0];
if(nums[0] < nums[size-1]) return nums[0];
int begin = 0;int end = size-1;
int midan;
while(begin < end-1)
{
midan = (begin+end)/2;
if(nums[midan] > nums[begin]) begin = midan;
else if(nums[midan] < nums[end]) end = midan;
}
return nums[end];
}
};
算法第四版:二叉搜索树增删改查的实现
class Node
{
public:
int key;
char value;
Node* left;
Node* right;
int N;
Node()
{
}
Node(int key, char value, int N)
{
this->key = key;
this->value = value;
this->N = N;
}
};
class BST:Node
{
Node* root;
public:
BST()
{
root = NULL;
}
int size(Node* r)
{
if (r == NULL) return 0;
return r->N;
}
char get(int key);
char get(Node* x, int key);
void insert(int key, char value);
Node* insert(Node* x, int key, int value);
int min();
Node* min(Node* x);
int select(int k);
Node* select(Node* x, int k);
int rank(int key);
int rank(int key, Node* x);
void deleteMin();
Node* deleteMin(Node* x);
void delete_BST(int key);
Node* delete_BST(Node* x, int key);
};
char BST::get(int key)
{
char result = '\0';
if (root == NULL) return result;
return get(root, key);
}
char BST::get(Node* x, int key)
{
char result = '\0';
if (x == NULL) return result;
if (x->key == key) return x->value;
if (x->key < key) return get(x->right, key);
if (x->key > key) return get(x->left, key);
}
void BST::insert(int key, char value)
{
root = insert(root, key, value);
}
Node* BST::insert(Node* x, int key, int value)
{
if (x == NULL)
{
Node* NewNode = new Node(key,value,1);
return NewNode;
}
if (x->key < key) x->right = insert(x->right, key, value);
else if (x->key > key) x->left = insert(x->left, key, value);
else if (x->key == key) x->value = value;
x->N = size(x->left) + size(x->right) + 1;
return x;
}
int BST::min()
{
Node* result = min(root);
if (root == NULL) return 0;
return result->key;
}
Node* BST::min(Node* x)
{
if (x == NULL) return NULL;
if (x->left != NULL) return min(x->left);
return x;
}
int BST::select(int k)
{
Node* result = select(root, k);
if (result == NULL) return 0;
return result->key;
}
Node* BST::select(Node* x, int k)
{
if (x == NULL) return NULL;
int t = 0;
if (x->left != NULL) t = size(x->left);
if (t < k) return select(x->right, k - 1 - t);
if (t == k) return x;
if (t > k) return select(x->left, k);
}
void BST::deleteMin()
{
if (root == NULL) return;
Node* result = deleteMin(root);
//delete result;
//result = NULL;
}
/*
Node* BST::deleteMin(Node* x)
{
if (x == NULL) return NULL;
Node* dMin = min(x);
if (dMin == NULL) return NULL;
*dMin = *(dMin->right);
return dMin;
}*/
Node* BST::deleteMin(Node* x)
{
if (x == NULL) return NULL;
if (x->left == NULL) return x->right;
x->left = deleteMin(x->left);
x->N = size(x->left) + size(x->right) + 1;
return x;
}
int BST::rank(int key)
{
return rank(key, root);
}
int BST::rank(int key, Node* x)
{
if (x == NULL) return 0;
int t = x->left == NULL ? 0 : x->left->N;
if (x->key > key) return rank(key, x->left);
if (x->key == key) return t;
if (x->key < key) return rank(key, x->right) + t + 1;
}
void BST::delete_BST(int key)
{
delete_BST(root, key);
}
Node* BST::delete_BST(Node* x, int key)
{
if (x == NULL) return NULL;
if (key == x->key)
{
if (x->right == NULL) return x->left;
if (x->left == NULL) return x->right;
Node* p = x;
x = min(x->right);
if (x == NULL) return x->left;
x->left = p->left;
x->right = deleteMin(p->right);
delete p;
p = NULL;
}
else if (key < x->key) x->left = delete_BST(x->left, key);
else if (key > x->key) x->right = delete_BST(x->right, key);
x->N = size(x->left) + size(x->right) + 1;
return x;
}
leetcode:154. 寻找旋转排序数组中的最小值 II
class Solution {
public:
int sort(vector<int>& nums)
{
int size = nums.size();
int result = nums[0];
for(int i = 1;i<size;++i) result = result > nums[i] ? nums[i] : result;
return result;
}
int findMin(vector<int>& nums)
{
int result;
int size = nums.size();
if(size == 1) return nums[0];
int left = 0;
int right = size-1;
if(nums[0] < nums[right]) return nums[0];
int midan;
while(left < right-1)
{
midan = (left+right)>>1;
if(nums[midan] == nums[left] && nums[midan] == nums[right])
{
result = sort(nums);
return result;
}
if(nums[midan] < nums[left]) right = midan;
else if(nums[midan] > nums[right]) left = midan;
}
return nums[right];
}
};
leetcode:11. 盛最多水的容器
class Solution {
public:
int maxArea(vector<int>& height)
{
int size = height.size();
if(size <= 1) return 0;
int left = 0;
int right = size-1;
int result = 0;
while(left<right)
{
int tim = height[left]<height[right]?height[left]:height[right];
result = result > ((right - left)*tim) ? result : ((right - left)*tim);
if(height[left] < height[right]) ++left;
else --right;
}
return result;
}
};
leetcode:题目号:200 575 695 268 674 135 代码略
leetcode:560 209 112 113 108
左神书题:最大值减去最小值小于等于num的子数组数量
leetcode:795
class Solution {
public:
int numSubarrayBoundedMax(vector<int>& arr, int max)
{
int ret = 0;
int temp = 0;
int size = arr.size();
for(int i=0;i<size;++i)
{
if(arr[i] <= max)
{
temp++;
ret+=temp;
}
else temp = 0;
}
return ret;
}
int numSubarrayBoundedMax(vector<int>& arr, int L, int R)
{
// 最大元素满足大于等于L小于等于R的子数组个数 = 最大元素小于等于R的子数组个数 - 最大元素小于L的子数组个数
int size = arr.size();
if(size == 0) return 0;
return numSubarrayBoundedMax(arr,R)-numSubarrayBoundedMax(arr,L-1);
}
};
leetcode: 98 35 104 110 111 102
leetcode:96不同的二叉搜索树
/*结题思路:假设n个节点存在二叉排序树的个数是G(n),1为根节点,2为根节点,...,n为根节点,当1为根节点时,其左子树节点个数为0,右子树节点个数为n-1,同理当2为根节点时,其左子树节点个数为1,右子树节点为n-2,所以可得G(n) = G(0)*G(n-1)+G(1)*(n-2)+...+G(n-1)*G(0)*/
class Solution {
public int numTrees(int n)
{
if(n<2) return 1;
int[] arr = new int [n+1];
arr[0] = 1;
arr[1] = 1;
for(int i=2;i<n+1;++i)
{
for(int j=0;j<i;++j)
{
arr[i] += arr[j]*arr[i-1-j];
}
}
return arr[n];
}
}
//c++溢出 所以用java
leetcode:100,94,230,144,116,117,111 ,129 130 199 96 137 141 142 287 101 222 235 236 404
在两个长度相等的排序数组中找到上中位数
84 85 221 513 542 718 581 27 283 485 1004
1 15 34 42 53 121 122 62 63
75 88 167 653 344 345 215
342 231 191 338 349 350
242 438 290 205 525
451 347 49 快速幂 1002 56 204