剑指offer
1.旋转数组中的最小数字
描述:有一个长度为 n 的非降序数组,把最开始的若干个元素搬到数组的末尾,变成一个旋转数组,求旋转后数组的最小值, 空间复杂度:O(1) ,时间复杂度:O(logn)
思路:二分法
int minNumberInRotateArray(vector<int> rotateArray) {
if (rotateArray.size() == 0) return 0
int first = 0, last = rotateArray.size() - 1
while (first < last) { // 最后剩下一个元素,即为答案
if (rotateArray[first] < rotateArray[last]) {
// 如果左端点值小于右端点值,根据初始给定的非递减数组的条件得知,提前退出
return rotateArray[first]
}
int mid = (first+last)/2
//情况一:把右端元素作为target,如果中值大于target,target一定在右半区
if (rotateArray[mid] > rotateArray[last]) first=mid+1
//情况二:如果中值小于target,target一定在左半区,中值有可能是target
else if (rotateArray[mid] < rotateArray[last]) last=mid
//情况三:例如{1,1,1,1,1},则缩小last范围,也能得出结论
else last--
}
return rotateArray[first]
}
2.矩阵中的路径
思路:回溯法
bool hasPath(vector<vector<char> >& matrix, string word) {
for (int i = 0; i < matrix.size(); i++)
{
for (int j = 0; j < matrix[0].size(); j++)
{
if (dfs(matrix, word, i, j, 0))
return true;
}
}
return false;
}
bool dfs(vector<vector<char>> matrix, string word, int i, int j, int index) {
if (i >= matrix.size() || i < 0 || j >= matrix[0].size() || j < 0 || matrix[i][j] != word[index])
return false;
if (index == word.size() - 1)
return true;
char tmp = matrix[i][j];
matrix[i][j] = '.';
bool res = dfs(matrix, word, i + 1, j, index + 1)
|| dfs(matrix, word, i - 1, j, index + 1)
|| dfs(matrix, word, i, j + 1, index + 1)
|| dfs(matrix, word, i, j - 1, index + 1);
matrix[i][j] = tmp;
return res;
}
3.二进制中1的个数
描述:输入一个整数 n ,输出该数32位二进制表示中1的个数。其中负数用补码表示。
int NumberOf1(int n) {
int ans = 0
while (n != 0) {
++ans
n = n & (n-1)
}
return ans
}
4.数值的整数次幂
法一:暴力法
double Power(double b, int n) {
if (n < 0) {
b = 1 / b
n = -n
}
double ret = 1.0
for (int i=0
return ret
}
法二:快速幂法
double Power(double b, int n) {
if (n < 0) {//负数底倒指反
b = 1 / b
n = -n
}
double x = b
double ret = 1.0
while (n) {
if (n&1) {
ret *= x
}
x *= x
n >>= 1
}
return ret
}
5.删除链表节点
ListNode* deleteNode(ListNode* head, int val) {
ListNode * phead=new ListNode(-1)
phead->next=head
if(!head) return head
if(head->val==val) phead->next=phead->next->next
while(head->next)
{
if(head->next->val==val)
head->next=head->next->next
else
head=head->next
}
return phead->next
}
6.打印从1到最大的n位数
vector<int> printNumbers(int n) {
vector<int> v;
int m=1;
for(int i=0;i<n;i++) m*=10;
for(int i=1;i<m;i++)
v.push_back(i);
return v;
}
7.调整数组顺序,使奇数位于偶数前面,并报持相对位置不变
法一:借助辅助数组
法二:直接在数组中调整位置 时间复杂度O(n^2),空间复杂度O(1)。
vector<int> reOrderArray(vector<int>& array) {
int index=0
for(int i=0
{
if(array[i]%2!=0)
{
int tmp=array[i]
for(int j=i
{
array[j]=array[j-1]
}
array[index]=tmp
index++
}
}
return array
}
8.二叉树的镜像
法一:借助辅助栈
TreeNode* Mirror(TreeNode* pRoot) {
if(!pRoot) return nullptr
stack<TreeNode *> st
TreeNode * tmp
st.push(pRoot)
while(!st.empty())
{
TreeNode* node=st.top()
st.pop()
if(node->left) st.push(node->left)
if(node->right) st.push(node->right)
tmp = node->left
node->left=node->right
node->right=tmp
}
return pRoot
}
法二:递归
TreeNode* Mirror(TreeNode* pRoot) {
if(pRoot)
{
TreeNode* temp;
temp=pRoot->left;
pRoot->left=pRoot->right;
pRoot->right=temp;
pRoot->left=Mirror(pRoot->left);
pRoot->right=Mirror(pRoot->right);
}
return pRoot;
}
整合版
TreeNode* Mirror(TreeNode* pRoot) {
if(pRoot)
{
TreeNode* temp;
temp=Mirror(pRoot->left);
pRoot->left=Mirror(pRoot->right);
pRoot->right=temp;
}
return pRoot;
}