初级算法 - 数组篇完结:
初级算法 - 数组(一):
https://blog.csdn.net/weixin_43854928/article/details/121315702
初级算法 - 数组(二):
https://blog.csdn.net/weixin_43854928/article/details/121523946
初级算法 - 数组(三):
https://blog.csdn.net/weixin_43854928/article/details/121568562
26. 删除有序数组中的重复项
给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
示例 2:
输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4]
解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。
链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array
思路:数组已经排好序了,从第0个元素作为对比项(cur_index),对比之后的元素是否与对比项相同,相同则跳过,不相同则更新为对比项,计数count++,并赋值到第count个元素中。
时间复杂度:O(n)
空间复杂度:O(1)
int removeDuplicates(int* nums, int numsSize)
{
if(numsSize == 0)
{
return 0;
}
short count = 1;
short cur_index = 0;
for(short i = 1; i<numsSize; i++)
{
if(nums[i] != nums[cur_index])
{
if(count != i)
{
nums[count] = nums[i];
}
count++;
cur_index = i;
}
}
return count;
}
122. 买卖股票的最佳时机 II
给定一个数组 prices ,其中 prices[i] 是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例1: 输入: prices = [7,1,5,3,6,4] 输出:
7 解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 =4 。
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii
思路:找到山峰和山谷,山峰卖出,山谷买入。山峰的特点是下一个元素开始变小,即为山峰,山谷的特点是下一个元素开始变大,即为山谷。注意最后一个交易日如果不是卖出,要把当前的持有全部卖出。
时间复杂度:O(n)
空间复杂度:O(1)
int maxProfit(int* prices, int pricesSize)
{
int buy_prices = 0;
int profit_count = 0;
char buy_flag = false;
for(short i = 1; i< pricesSize; i++)
{
if(prices[i] > prices[i-1] && !buy_flag)
{
buy_prices = prices[i-1];
buy_flag = true;
}
else if(prices[i] < prices[i-1] && buy_flag)
{
profit_count += prices[i-1] - buy_prices;
buy_flag = false;
}
}
if(buy_flag)
{
profit_count += prices[pricesSize-1] - buy_prices;
}
return profit_count;
}
189. 轮转数组
给你一个数组,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。
示例 1: 输入: nums = [1,2,3,4,5,6,7],
k = 3 输出: [5,6,7,1,2,3,4]
解释: 向右轮转 1 步: [7,1,2,3,4,5,6]
向右轮转 2 步:[6,7,1,2,3,4,5]
向右轮转 3 步: [5,6,7,1,2,3,4]
链接:https://leetcode-cn.com/problems/rotate-array
思路:
- 先将k对数组长度取余,因为整圈数的轮转没有意义。
- 整个数组反转,然后按取余后的temp_k将数组分成前后两部分,两部分再分别反转。
时间复杂度:O(n)
空间复杂度:O(1)
void rotate(int* nums, int numsSize, int k)
{
int temp_k = k%numsSize;
if(numsSize == 1 || temp_k == 0)
{
return;
}
for(int i = 0; i<numsSize/2; i++)
{
int temp = nums[i];
nums[i] = nums[numsSize-i-1];
nums[numsSize-i-1] = temp;
}
for(int i = 0; i<temp_k/2; i++)
{
int temp = nums[i];
nums[i] = nums[temp_k-i-1];
nums[temp_k-i-1] = temp;
}
for(int i = 0; i<(numsSize-temp_k)/2; i++)
{
int temp = nums[i+temp_k];
nums[i+temp_k] = nums[numsSize-i-1];
nums[numsSize-i-1] = temp;
}
}
217. 存在重复元素
给定一个整数数组,判断是否存在重复元素。
如果存在一值在数组中出现至少两次,函数返回 true 。如果数组中每个元素都不相同,则返回 false 。
示例 1:
输入: [1,2,3,1]
输出: true
示例 2:
输入: [1,2,3,4]
输出: false
链接:https://leetcode-cn.com/leetbook/read/top-interview-questions-easy/x248f5/
思路:一开始的思路是先把数组排序,排序后从前往后遍历nums[i]和nums[i+1]是否相等。
为了防止执行超时用的快速排序:
void quick_sort(int* low, int* high)
{
if (low >= high) //排序结束
{
return;
}
int *i = low, *j = high;
const int key = *low;
while(i<j)
{
while(*j >= key && i<j)
{
j-=1;
}
if(*j < key)
{
*i = *j;
*j = key;
i+=1;
}
while(*i <= key && i<j)
{
i+=1;
}
if(*i > key)
{
*j=*i;
*i = key;
j-=1;
}
}
quick_sort(low, i-1);
quick_sort(i+1, high);
}
bool containsDuplicate(int* nums, int numsSize)
{
if(numsSize<2)
{
return false;
}
quick_sort(nums, nums+numsSize-1);
for(int i = 0; i<numsSize-1; i++)
{
if(nums[i] == nums[i+1])
{
return true;
}
}
return false;
}
结果还是超时了。
没办法只能手写了一个hash map,执行时间满足了要求,但内存占用要高出很多:
struct hash_node
{
char flag;
int number;
struct hash_node* next;
};
bool add_hash_node(int data_num, int numsSize, struct hash_node* hash_map)
{
int key = (data_num&0x7FFFFFFF)%numsSize;
struct hash_node* node = &hash_map[key];
struct hash_node* next_node = node;
do
{
node = next_node;
if(!node->flag)//空
{
node->number = data_num;
node->flag = 1;
return false;
}
else
{
if(node->number == data_num)
{
return true;
}
}
next_node = node->next;
}
while(next_node);
node->next = calloc(1, sizeof(struct hash_node));
node->number = data_num;
node->flag = 1;
return false;
}
bool containsDuplicate(int* nums, int numsSize)
{
struct hash_node hash_map[numsSize];
memset(hash_map, 0, sizeof(hash_map));
for(int i = 0; i< numsSize; i++)
{
if(add_hash_node(nums[i], numsSize, hash_map) == true)
{
return true;
}
}
return false;
}