数据结构OJ题

这篇具有很好参考价值的文章主要介绍了数据结构OJ题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1.字符串左旋 

2.字符串旋转结果

3.旋转数组

4.移除元素


本篇主要是讲解一些OJ题目。

1.字符串左旋 

字符串左旋

实现一个函数,可以左旋字符串中的k个字符

例如:

ABCD左旋一个字符得到BCDA

ABCD左旋两个字符得到CDAB

方法1【暴力求解】

  • 翻转1个字符
  1. 创建一个中间变量tmp,用于存储翻转的字符
  2. 把后面的字符向前覆盖移动
  3. 把tmp存储的字符放到结尾
  • 翻转k个字符,循环k次即可 
  • 注意如果旋转超出数组的元素个数范围,需要现处理一下。k=%len
#include<stdio.h>
void left_move(char* arr, int sz,int k)
{
	int i = 0;
	for (i = 0; i < k; i++)//k次
	{
		//一次翻转
		char tmp = 0;//1.
		tmp = *arr;
		int j = 0;//2.
		for (j = 0; j < sz - 2; j++)
		{
			arr[j] = arr[j + 1];
		}
		arr[sz - 2] = tmp;//3.
	}
}
int main()
{
	char arr[] = "ABCDEF";
	int sz = sizeof(arr) / sizeof(arr[0]);//计算了\0
	int k = 0;
	scanf_s("%d", &k);
	k = k % (sz - 1);
	left_move(arr, sz,k);
	printf("%s", arr);
	return 0;
}

数据结构OJ题,初阶数据结构,c语言,数据结构


方法2【三步翻转】

  • 左边逆序
  • 右边逆序
  • 整体逆序
  • 封装一个逆序字符串的函数,传不同的起尾位置,调用三次函数即可
  • 注意如果旋转超出数组的元素个数范围,会造成数组越界的问题,需要现处理一下。k=%len
#include<stdio.h>
//逆序字符串函数
void reverse(char* begin, char* end)
{
	while (begin < end)
	{
		char tmp = 0;
		tmp = *begin;
		*begin = *end;
		*end = tmp;
		begin++;
		end--;
	}
}
int main()
{
	char arr[] = "ABCDEF";
	int sz = sizeof(arr)/sizeof(arr[0]);
	int k = 0;
	scanf_s("%d", &k);
	k = k % (sz - 1);//必须有不然会数组越界
	reverse(arr, arr + k-1);
	reverse(arr + k, arr + sz - 2);
	reverse(arr, arr + sz - 2);
	printf("%s", arr);
	return 0;
}

数据结构OJ题,初阶数据结构,c语言,数据结构


2.字符串旋转结果

字符串旋转结果

写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。

例如:

给定s1= AABCD和s2 = BCDAA,返回1

给定s1=abcd和s2=ABCD,返回0

方法1【暴力求解】

  • 旋转1次比较1次
  • 把所有结果都列出来一一比较,如果没有那就返回0.
  • 注意:如果两个数组的长度不一样,是肯定不会旋转得到的,需要处理一下。
#include<stdio.h>
#include<string.h>
#include<assert.h>
int is_left_move(char* arr1, const char* arr2)
{
	assert(arr1 && arr2);
	int len1 = strlen(arr1);
	int len2 = strlen(arr2);
	if (len1 != len2)
	{
		return 0;
	}
	int i = 0;
	//这里如果用while  len是变化的
	for(i=0;i<len1;i++)
	{
		//一次翻转
		char tmp = 0;//1.
		tmp = *arr1;
		int j = 0;//2.
		for (j = 0; j < len1 - 1; j++)
		{
			arr1[j] = arr1[j + 1];
		}
		arr1[len1 - 1] = tmp;//3
		//判断
		if (strcmp(arr1, arr2) == 0)
		{
			return 1;
		}
	}
	return 0;
}
int main()
{
	char arr1[] = "ABCDEF";
	char arr2[] = "CDEFAB";
	int ret=is_left_move(arr1, arr2);
	if (ret == 1)
	{
		printf("YES");
	}
	else
	{
		printf("NO");
	}
	return 0;
}

 数据结构OJ题,初阶数据结构,c语言,数据结构


方法2【追加找子串 】

  • 把原字符串数组arr1追加,这样翻转所有的可能性都在追加字符串里
  • 再去arr1追加字符串里找子串arr2,看是否和要比较字符串数组arr2,相符号的。
  • 注意:如果两个数组的长度不一样,是肯定不会旋转得到的,需要处理一下。
#include<stdio.h>
#include<string.h>
#include<assert.h>
int is_left_move(char* arr1, const char* arr2)
{
	assert(arr1 && arr2);
    int len1 = strlen(arr1);
	int len2 = strlen(arr2);
	if (len1 != len2)
	{
		return 0;
	}

	int len = strlen(arr1);
	strncat(arr1, arr1, len);
	if (strstr(arr1, arr2) == NULL)
		return 0;
	else
		return 1;
}
int main()
{
	char arr1[] = "ABCDEF";
	char arr2[] = "CDEFAB";
	int ret=is_left_move(arr1, arr2);
	if (ret == 1)
	{
		printf("YES");
	}
	else
	{
		printf("NO");
	}
	return 0;
}

数据结构OJ题,初阶数据结构,c语言,数据结构


3.旋转数组

给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。

输入: nums = [1,2,3,4,5,6,7], k = 3
输出: [5,6,7,1,2,3,4]
输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]

方法1【暴力求解】

同上

时间复杂度:O(N^2)

#include<stdio.h>
#include<string.h>
#include<assert.h>
void right_move(char* arr,int k)
{
	assert(arr);
	int len = strlen(arr);
    k%=len;
	int i = 0;
	for (i = 0; i < k; i++)
	{
		int j = 0;
		char tmp = arr[len - 1];
		for (j = len-1; j >0; j--)
		{
			arr[j] = arr[j -1];
		}
		*arr = tmp;
	}
}
int main()
{
	char arr[] = "ABCDEF";
	int k = 0;
	scanf("%d", &k);
	right_move(arr,k);
	printf("%s", arr);
	return 0;
}

数据结构OJ题,初阶数据结构,c语言,数据结构


方法2【三步翻转】

界限:需要右旋&不需要右旋的逆置,整体逆置

时间复杂度:O(N) 

#include<stdio.h>
//逆序字符串函数
void reverse(char* begin, char* end)
{
	while (begin < end)
	{
		char tmp = 0;
		tmp = *begin;
		*begin = *end;
		*end = tmp;
		begin++;
		end--;
	}
}
int main()
{
	char arr[] = "ABCDEF";
	int len = strlen(arr);
	int k = 0;
	scanf_s("%d", &k);
	k = k % len;//必须有不然会数组越界
	reverse(arr,arr+len-k-1);
	reverse(arr+len-k,arr+len-1);
	reverse(arr,arr+len-1);
	printf("%s", arr);
	return 0;
}

方法3【以时间换空间】

  • 先拷贝前len-k个到后面位置
  • 再拷贝k个 到前面位置
  • 最后拷贝回去
  • 变长数组和动态内存开辟的数组都可
  • 关键就是下标和位置一定一定控制清楚
  • 时间复杂度:O(N)       空间复杂度:O(N)

数据结构OJ题,初阶数据结构,c语言,数据结构

void rotate(int* nums, int numsSize, int k)
{
    int tmp[numsSize];
    int i=0;
    k%=numsSize;//就这个代码卡了我一下午,有时候真的很无助
    for(i=0;i<k;i++)
    {
        *(tmp+i)=*(nums+numsSize-k+i);
    }
    for(i=0;i<numsSize-k;i++)
    {
        *(tmp+k+i)=*(nums+i);
    }
    for(i=0;i<numsSize;i++)
    {
        *(nums+i)=*(tmp+i);
    }
}

 数据结构OJ题,初阶数据结构,c语言,数据结构


4.移除元素

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。

方法1【暴力求解】

  • 首先遍历数组一遍找到元素
  • 从后向前依次覆盖
  • 时间复杂度:O(N^2)
int removeElement(int* nums, int numsSize, int val)
{
    int i=0;
    for(i=0;i<numsSize;i++)
    {
        if(nums[i] == val)
        {
            for(;i<numsSize-i;i++)//❌
            nums[i]=nums[i+1];
        }
    }
    return numsSize;
}

方法2【以空间换时间】

  • 创建一个一摸一样的数组tmp
  • 把是val的数值元素留下,不是的拷贝到tmp中
  • 最后把tmp拷贝到nums里面去
  • 时间复杂度:O(N)

数据结构OJ题,初阶数据结构,c语言,数据结构 但是我们发现,题目要求不允许这么做?怎么办呢? 


方法3【方法2的优化】

那我们选择就在nums的基础上实现tmp等的功能。

  • 使用src指针和des指针
  • 时间复杂度O(N)

数据结构OJ题,初阶数据结构,c语言,数据结构

int removeElement(int* nums, int numsSize, int val){
int src=0;
int dst=0;
while(src<numsSize)
{
    if(nums[src] != val)
    {
        nums[dst++]=nums[src++];
    }
    else
    {
        src++;
    }
}
  return dst;
}

【暴力求解】&【三步翻转】 

【注意】 

  • len&sz
  • 指针&数组下标
  • 如果找错了位置或者减少了都会发生错误❌

数据结构OJ题,初阶数据结构,c语言,数据结构

✔✔✔✔✔最后,感谢大家的阅读,若有错误和不足,欢迎指正! 棠棣

代码---------→【唐棣棣 (TSQXG) - Gitee.com】

联系---------→【邮箱:2784139418@qq.com】文章来源地址https://www.toymoban.com/news/detail-738509.html

到了这里,关于数据结构OJ题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C语言完整版笔记(初阶,进阶,深刨,初阶数据结构)

    1.初阶: 1.1C语言初阶易忘知识点速记 2.进阶:  1.2C语言进阶易忘点速记 3.深剖: 2.1C语言重点解剖要点速记 2.2C语言重点解剖操作符要点速记   2.3C语言重点解剖预处理要点速记 2.4C语言重点解剖指针和数组要点速记 2.5C语言重点解剖内存管理函数要点速记 4.数据结构:

    2024年02月16日
    浏览(28)
  • 数据结构初阶(用C语言实现简单数据结构)--栈和队列

    ✨✨欢迎来到T_X_Parallel的博客!!       🛰️博客主页:T_X_Parallel       🛰️专栏 : 数据结构初阶       🛰️欢迎关注:👍点赞🙌收藏✍️留言 这小猫真好看 言归正传,通过上篇有关顺序表和链表的博客,可以了解到线性表的一些大致特征,这篇博

    2024年02月08日
    浏览(28)
  • 【数据结构初阶】之堆(C语言实现)

    前言 :在二叉树基础篇我们提到了二叉树的顺序实现,今天让我们来学习一下特殊的二叉树———堆的相关知识。 📃 博客主页: 小镇敲码人 💞 热门专栏:数据结构与算法 🚀 欢迎关注:👍点赞 👂🏽留言 😍收藏 🌏 任尔江湖满血骨,我自踏雪寻梅香。 万千浮云遮碧月

    2024年04月09日
    浏览(74)
  • 【数据结构】C语言实现顺序栈 && OJ题 —— 有效的括号

    👑作者主页:@进击的安度因 🏠学习社区:进击的安度因(个人社区) 📖专栏链接:数据结构

    2024年02月10日
    浏览(34)
  • 『初阶数据结构 • C语言』④ - 冒泡排序

      本文内容借鉴一本我非常喜欢的书——《数据结构与算法图解》。学习之余,我决定把这本书精彩的部分摘录出来与大家分享。      本章内容 写在前面 1.冒泡排序 2.冒泡排序实战 3.冒泡排序的实现 4.冒泡排序的效率 5.二次问题 6.线性解决 7.总结     大 O记法能客观地衡量

    2024年02月16日
    浏览(31)
  • 『初阶数据结构 • C语言』⑤ - 选择排序

    本文内容借鉴一本我非常喜欢的书——《数据结构与算法图解》。学习之余,我决定把这本书精彩的部分摘录出来与大家分享。     目录 写在前面 1.选择排序 2.选择排序实战 3.选择排序的实现 4.选择排序的效率 5.忽略常数 6.大O的作用 7.总结     大 O 是一种能够比较算法效

    2024年02月14日
    浏览(32)
  • 『初阶数据结构 • C语言』② - 算法为何重要

    本文内容借鉴一本我非常喜欢的书——《数据结构与算法图解》。学习之余,我决定把这本书精彩的部分摘录出来与大家分享。   算法这个词听起来很深奥,其实不然。它只是解决某个问题的一套流程。  准备一碗麦片的流程也可以说是一种算法,它包含以下 4步(对我来说

    2024年02月14日
    浏览(26)
  • 『初阶数据结构 • C语言』⑥ - 插入排序&希尔排序

    学习目标 写在前面 1.插入排序 2.插入排序实战  3.插入排序的实现  4.插入排序的效率 5.平均情况 6.希尔排序 7.希尔排序的实现 8.希尔排序的效率 9.总结   之前我们衡量一个算法的效率时,都是着眼于它在最坏情况下需要多少步。原因很简单,连最坏的情况都做足准备了,其

    2024年02月15日
    浏览(31)
  • 数据结构初阶之顺序表(C语言实现)

    顺序表是数据结构里面很基础的一类,它是线性表的一种,其它线性表还有链表、栈和队列等,今天来和博主一起学习关于顺序表的知识吧。 顺序表,它分为两类: 动态顺序表 和 静态顺序表 ,这两个表的区别就是 前者的空间不固定 ,是 支持扩容 的,后者的 空间是固定

    2024年02月03日
    浏览(34)
  • 初阶数据结构之---顺序表和链表(C语言)

    线性表: 线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构。线性表在逻辑上是线性结构,也就是说是连续的一条直线。但在物理上并不一定是连续的。线性表在物理上存储时,通常以 数组 和 链式结构 的形式存储。

    2024年02月22日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包