目录
1.买卖股票的最佳时机
【题目】
【分析】动态规划——贪心法
1:因为严格按照时间的先后顺序执行,一定要先买,在卖
2:遍历数组维护两个变量最大的利润和min最小价格。
3:如果当前价格小于最小的值min时,更新min的值。
4:当前价格与最小值min得差值大于ans时,更细ans的值
3:返回ans的值
时间复杂度:O(n)
空间复杂度:O(1)
int maxProfit(int* prices, int pricesSize){
int min=prices[0],ans=0;
for(int i=0;i<pricesSize;++i){
if(prices[i]<min){
min=prices[i];
}
if(ans<prices[i]-min){
ans=prices[i]-min;
}
}
return ans;
}
2.买卖股票的最佳时机之2
【题目】
【分析】贪心法
int maxProfit(int* prices, int pricesSize) {
int ans = 0;
for (int i = 1; i < pricesSize; ++i) {
ans += fmax(0, prices[i] - prices[i - 1]);
}
return ans;
}
3.单词搜索
【题目】
【分析】
bool DFS(char** board, bool **visited, int rows, int cols, int i, int j, char * word, int index) {
if (i < 0 || j < 0 || i >= rows || j >= cols || visited[i][j] || board[i][j] != word[index]) {
return false;
}
if (index == strlen(word) - 1) {
return true;
}
visited[i][j] = true;
bool res = DFS(board, visited, rows, cols, i + 1, j, word, index + 1) ||
DFS(board, visited, rows, cols, i - 1, j, word, index + 1) ||
DFS(board, visited, rows, cols, i, j + 1, word, index + 1) ||
DFS(board, visited, rows, cols, i, j - 1, word, index + 1);
visited[i][j] = false;
return res;
}
bool exist(char** board, int boardSize, int* boardColSize, char * word){
bool **visited = (bool **)calloc(boardSize, sizeof(bool *));
for (int i = 0; i < boardSize; i++) {
visited[i] = (bool *)calloc(boardColSize[i], sizeof(bool));
}
for (int i = 0; i < boardSize; i++) {
for (int j = 0; j < boardColSize[i]; j++) {
if (DFS(board, visited, boardSize, boardColSize[i], i, j, word, 0)) {
return true;
}
}
}
return false;
}
int r,c,wordLen;
bool check;
void backTracking(char** board,bool visited[][c],char* word,int index,int i,int j)
{
if(i<0||i>=r||j<0||j>=c||visited[i][j]||check||word[index]!=board[i][j])
return;//如果下标越界或者匹配成功(check=true)或者单词不匹配就返回
if(index+1==wordLen)//不满足上面说明匹配成功,此时看是否已匹配完word
check=true;
visited[i][j]=true;//设置当前节点为已访问
backTracking(board,visited,word,index+1,i+1,j);//分别向四个方向进行回溯
backTracking(board,visited,word,index+1,i-1,j);
backTracking(board,visited,word,index+1,i,j+1);
backTracking(board,visited,word,index+1,i,j-1);
visited[i][j]=false;//返回先前状态
}
//主函数就不解释了
bool exist(char** board, int boardSize, int* boardColSize, char * word){
bool** visited[boardSize][boardColSize[0]];
r=boardSize,c=boardColSize[0],wordLen=strlen(word),check=false;
memset(visited,0,sizeof(visited));
for(int i=0;i<r;i++)
for(int j=0;j<c;j++)
{
backTracking(board,visited,word,0,i,j);
if(check)
return true;
}
return false;
}
4.轮转数组
【题目】
给你一个数组,将数组中的元素向右轮转 k
个位置,其中 k
是非负数。
【分析】
法1:使用额外的数组将每个元素放至正确的位置。用 n 表示数组的长度,我们遍历原数组,将原数组下标为 iii 的元素放至新数组下标为 (i+k) mod n的位置,最后将新数组拷贝至原数组即可。
void rotate(int* nums, int numsSize, int k) {
int newArr[numsSize];
for (int i = 0; i < numsSize; ++i) {
newArr[(i + k) % numsSize] = nums[i];
}
for (int i = 0; i < numsSize; ++i) {
nums[i] = newArr[i];
}
}
法2:数组翻转
void swap(int* a, int* b) {
int t = *a;
*a = *b, *b = t;
}
void reverse(int* nums, int start, int end) {
while (start < end) {
swap(&nums[start], &nums[end]);
start += 1;
end -= 1;
}
}
void rotate(int* nums, int numsSize, int k) {
k %= numsSize;
reverse(nums, 0, numsSize - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, numsSize - 1);
}
5.快慢指针
【题目】
【分析】
法1:单链表遍历法
struct ListNode* middleNode(struct ListNode* head){
int len=0;//表长
int j=0;
struct ListNode* cur=head;//指向链表头
while(cur!=NULL){
cur=cur->next;
len++;
}//找链表长度
cur=head;//重新指向链表头
while(j<len/2&&cur!=NULL){
cur=cur->next;
j++;
}
return cur;
}
法2:快慢指针
以1 2 3 4 5 6 为例,i代表慢指针(每次移动1步),j代表快指针(每次移动2步)。
(1)刚开始i和j都指向头节点
1 2 3 4 5 6
i
j
(2)第一轮移动快慢指针后i和j的位置
1 2 3 4 5 6
i
j
(3)第二轮移动快慢指针后i和j的位置
1 2 3 4 5 6
i
j
(4)第三轮移动快慢指针后i和j的位置(当j移动到链表尾部NULL时,i刚好是答案)
1 2 3 4 5 6 NULL
i
j
struct ListNode* middleNode(struct ListNode* head){
struct ListNode* fast=head;//快指针一次走两步
struct ListNode* slow=head;//慢指针一次走一步
while(fast!=NULL&&fast->next!=NULL){//也要判断下一个是不是为空指针
slow=slow->next;
fast=fast->next->next;
}
return slow;
}
6.翻转字符串中的单词3
【题目】
【分析】
直接在原字符串上进行操作,避免额外的空间开销。当找到一个单词的时候,我们交换字符串第一个字符与倒数第一个字符,随后交换第二个字符与倒数第二个字符……如此反复,就可以在原空间上翻转单词
char * reverseWords(char * s){
int length=strlen(s);
int left,right;
int start;
int i=0;
while(i<length){
start=i;
while(i<length&&s[i]!=' '){
i++;
}
left=start;
right=i-1;
while(left<right){
char tmp=s[left];
s[left]=s[right];
s[right]=tmp;
left++;
right--;
}
while(i<length&&s[i]==' '){
i++;
}
}
return s;
}