1.轮转数组
题目:轮转数组
定义程序目标
数组元素右移,当数组元素越界时回到数组开头。
设计程序
循环k次
保存数组的最后一个元素
每次将数组的所有元素右移一位
将数组首元素置为数组最后一个元素
void rotate(int* nums, int numsSize, int k) {
k%=numsSize;
while(k--)
{
int end=nums[numsSize-1];
for(int i=numsSize-1;i>0;i--)
{
nums[i]=nums[i-1];
}
nums[0]=end;
}
}
嵌套循环,时间复杂度为O(N 2)
设计程序
开辟一个新数组
循环N次(元素总个数)用题目所给数组[下标]对新数组[(数组下标+右移次数)%元素总数]进行赋值
循环N次
用新数组[下标]]对题目所给数组数组[下标]进行赋值。
void rotate(int* nums, int numsSize, int k) {
int*NewArr=(int*)malloc(sizeof(int)*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];
}
}
时间复杂度为O(N)
设计程序
提供一个接口对数组进行逆置
将(N-K%7)元素逆置
将(K%7)元素逆置
将所有元素逆置
void reverse(int* nums,int left,int right)//进行逆置
{
while(left<right)
{
int tmp=nums[left];
nums[left]=nums[right];
nums[right]=tmp;
left++;
right--;
}
}
void rotate(int* nums, int numsSize, int k) {
k%=numsSize;
reverse(nums,0,numsSize-1-k);
reverse(nums,numsSize-k,numsSize-1);
reverse(nums,0,numsSize-1);
}
时间复杂度为O(1)
2.移除元素
移除元素
设计程序
定义两个指针soure和des,同时指向开头
遍历数组当source不等于val时,soure和des同时++,将soure赋值给des
当source数值等于val时,des不变,soure++。
重复以上过程直到soure遍历完数组,此时des的大小就是有效数据的大小返回des
int removeElement(int* nums, int numsSize, int val) {
int src = 0, dst = 0;
while (src < numsSize) {
if (nums[src] == val) {
src++;
} else {
nums[dst] = nums[src];
dst++;
src++;
}
}
return dst;
}
当然还可以优化用for循环
int removeElement(int* nums, int numsSize, int val) {
int des=0,src=0;
for(;src<numsSize;src++)
{
if(nums[src]!=val)
{
nums[des]=nums[src];
des++;
}
}
return des;
}
3.删除有序数组中的重复项
删除有序数组中的重复项
设计程序
大题思路与上一道题相同
定义两个指针soure和des,同时des指向开头,soure指向后一个元素
遍历数组当source等于des时有重复元素了,soure++。
当source数值不等于des时,des++,将source赋值给++后的des,source++。
重复以上过程知道soure遍历完数组,此时des+1的大小就是有效数据的大小返回des+1。
int removeDuplicates(int* nums, int numsSize) {
int des=0,src=1;
for(;src<numsSize;src++)
{
if(nums[src]!=nums[des])
{
des++;
nums[des]=nums[src];
}
}
return des+1;
}
我就不赘述while循环怎么写了
4.合并两个有序数组
合并两个有序数组
设计程序
定义三个指针l1,l2,l3。l1指向num1(小)的末尾,l2指向num2的末尾,l3指向num1(大)的末尾
遍历数组(注意非递减顺序也就是递增末尾数据为最大)
当l1>l2,将l1(小)赋给l1(大)的末尾,l1–,l3–。
当l1<l2,将l2赋给l1(大)的末尾,l2–,l3–。
重复以上过程退出循环此时要么l1(小)遍历完了,要么l2遍历完了。如果是l2遍历完了程序结束,如果是l1遍历完了,还要将l2剩余的元素赋给l1(大)自己代入数据就会很清楚为什么我们只处理l2不处理l1(小)了
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
int l1=m-1,l2=n-1,l3=m+n-1;
while(l1>=0&&l2>=0)
{
if(nums1[l1]>nums2[l2])
{
nums1[l3--]=nums1[l1--];
}
else
nums1[l3--]=nums2[l2--];
}
while(l2>=0)
{
nums1[l3--]=nums2[l2--];
}
}