目录
一 二维数组中的查找 找target 2/27
题目描述:在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
思路:
- 习惯使用双指针,然后嵌套循环;时间O(nlogn) 空间O(n);
- 如果行和列有一个较大,选择循环较小的那个(待解决);
class Solution {
public:
bool Find(int target, vector<vector<int> > array) {
int row = (int)array.size();
int col = (int)array[0].size();
for(int i = 0; i < row; i++){
int left = 0, right = col - 1;
while(left <= right){
int middle = left + (right - left)/2;
if(array[i][middle] == target) return true;
else if(array[i][middle] > target) right = middle - 1;
else left = middle + 1;
}
}
return false;
}
};
//或者
class Solution {
public:
bool Find(int target, vector<vector<int> > array) {
int row = array.size();
int col = array[0].size();
for(int i = 0; i < col; i++){
int left = 0, right = row - 1;
while(left<= right){
int middle = left + (right - left)/2;
if(array[middle][i] == target) return true;
else if(array[middle][i] < target) left = middle + 1;
else right = middle - 1;
}
}
return false;
}
};
二 替换空格
- 双指针,从后往前遍历覆盖原字符串
【易错】错误出在‘\0’,无语
参考:https://www.cnblogs.com/codingmengmeng/p/5857143.html
class Solution {
public:
void replaceSpace(char *str,int length) {
if(str == NULL && length <= 0) return;
int oldLen = 0;
int blankLen = 0;
for(oldLen = 0; str[oldLen] != '\0'; oldLen++){
if(str[oldLen] == ' ') blankLen++;//遍历字符串,计数空字符数
}
int newLen = oldLen + blankLen*2;//计数新字符数
if(newLen > length) return;//若新字符串长度超过给定数组长度,返回空
str[newLen] = '\0';//新字符串末尾加\0
int p1 = oldLen - 1, p2 = newLen - 1;//设置快慢指针
//p1指向原字符串,p2指向新字符串
while(p1 >= 0 && p2 > p1){//从后往前覆盖掉原字符串
if(str[p1] == ' '){//找到空格,新字符串加字符
str[p2--] = '0';
str[p2--] = '2';
str[p2--] = '%';
}else{
str[p2--] = str[p1];//不是空字符,则复制原字符
}
p1--;
}
}
};
三 链表翻转(从尾到头打印链表)2/28
题目表述:输入一个链表,按链表从尾到头的顺序返回一个ArrayList。
- 1 参考https://blog.csdn.net/howe1233/article/details/88371887,利用reverse函数
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) :
* val(x), next(NULL) {
* }
* };
*/
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
vector<int> res;//新建一个vector
while(head != NULL){
res.push_back(head->val);//将链表放进res
head = head -> next;
}
reverse(res.begin(), res.end());//reverse翻转res
return res;//返回翻转后的值
}
};
- 2 栈的先进后出
参考https://www.cnblogs.com/zhonglixunta/articles/9523707.html
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) :
* val(x), next(NULL) {
* }
* };
*/
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
vector<int> res;//新建vector存放结果
stack<int> array;//新建栈
ListNode * p = head;
while(p != NULL){//将链表存放入堆栈
array.push(p -> val);
p = p -> next;
}
int len = array.size();
for(int i = 0; i < len; i++){
res.push_back(array.top());//将栈中的数据pop出
array.pop();
}
return res;
}
};
六 旋转数组的最小元素
题目描述:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
思路:
像leetcode里 search in rotated array2 在旋转后的的数组中寻找目标数字;
- 使用二分法;
有一个特殊情况:当数组中有【重复数字】,要忽略重复数字,再进入判断,即 mid = left; /mid = right; 则right--;
参考:https://www.cnblogs.com/grandyang/p/4040438.html
class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {
int left = 0, right = (int)rotateArray.size() - 1;
while(left < right){//注意是<,否则重复比较
int mid = left + (right - left) / 2;
if(rotateArray[mid] > rotateArray[right]) left = mid + 1;//左半段有序,比如{3423}
else if(rotateArray[mid] < rotateArray[right]) right = mid;//右半段有序,但是mid可能就是最小值,比如{3123},要注意这里的边界
else right--;//删除重复
}
return rotateArray[right];
}
};
经过查找和和LeetCode上153,154是一样的。只不过153的数组元素是不重复的,154则允许数组有重复元素。
这里直接要求输入的是非递减排序的数组,所以和154题是一样的。
参考:https://www.cnblogs.com/silentteller/p/11832273.html
- 分治法, 局部最小, 递归
【高亮】【注意边界】
class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {
if(rotateArray.empty()) return 0;
return find(rotateArray, 0, rotateArray.size() - 1);
}
//分割成左右两个数组,寻找有序的子数组中的最小值,如果子数组无序,则继续分割;
//判断数组是否有序:数组左边界小于右边界则有序
//当左右值相同,不能认为数组内元素值都相同,要继续分割,知道左边值 < 右边值
int find(vector<int>& nums, int l, int r){
if(nums[l] < nums[r] || l == r) return nums[l];
int mid = l + (r - l) / 2;
return min(find(nums, l, mid), find(nums, mid + 1, r));//
}
};
七 斐波那契数列
题目描述:大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。
- 需要注意的是这里起始项f(1) = 1, f(2) = 1, f(3) = 2;因此循环终止条件为n-1次
class Solution {
public:
int Fibonacci(int n) {
if(n == 0) return 0;//考虑特殊情况,第0项
int pre = 0;//前指针
int cur = 1;//后指针
for(int i = 1; i < n; i++){
int temp = cur;//临时指针保存当前的后指针
cur = cur + pre;//当前指针 = 前两项之和
pre = temp;//更新前指针为临时指针,前指针移到上一个后指针的位置上
}
return cur;
}
};
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
八 跳台阶
leetcode里写过 【动态规划】【斐波那契】
- 需要注意的是这里起始项f(1) = 1, f(2) = 2, f(3) = 3;因此【循环终止条件是n次】
class Solution {
public:
int jumpFloor(int number) {
int pre = 0;
int cur = 1;
for(int i = 1; i <= number; i++){//注意这里<=,可以由前三项测试得知
int temp = cur;
cur = cur + pre;
pre = temp;
}
return cur;
}
};
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
转存失败
重新上传
取消
转存失败重新上传取消
九变态爬楼梯
【递归】
- f(1) = 1, f(2) = 2, f(3) = 4, f(4) = 8, f(5) =16; f(n) = 2^n;
class Solution {
public:
int jumpFloorII(int number) {
if(number == 1) return 1;
if(number == 2) return 2;
return 2 * jumpFloorII(number - 1);
}
};
十 矩形覆盖
虽然我知道是斐波那契数列,但是我没看懂https://blog.csdn.net/qq_21583077/article/details/97644291
class Solution {
public:
int rectCover(int number) {
if(number == 0) return 0;
if(number == 1) return 1;
if(number == 2) return 2;
for(int i = 0; i < number; i++){
return rectCover(number - 1) + rectCover(number - 2);
}
}
};