这几天工作比较忙,今天整理下前两天完成的一个算法题。题目要求如下:
/牛牛拿到了一个字符串。
他每次“点击”,可以把字符串中相邻两个相同字母消除,例如,字符串"abbc"点击后可以生成"ac"。
但相同而不相邻、不相同的相邻字母都是不可以被消除的。
牛牛想把字符串变得尽可能短。他想知道,当他点击了足够多次之后,字符串的最终形态是什么?
输入
abbc
输出
ac
示例2
输入
abba
输出
0
示例3
输入
bbbbb
输出
b
补充:题目当然是不限制语言的,我工作中用到C#,所以我选择用C#。
思路1:用循环解决这个问题,这个是我最开始的思路。
1.首先是输入一长串字符串,把它传入char类型的一维数组(这里要注意的一点是不要直接使用静态一维数组,静态的是没有没办法进行删除元素操作的,我们传到动态数组里完成这个过程)。
2.然后满足条件的话从第二个值开始遍历,与第一个的值开始对比。如果满足条件就把两个值一起从数组里删除,然后再从新的数组里第二个值开始遍历,否则输出。
相信各位发现了我这里描述的时候产生的一个问题,就是遍历的次数过于多了,这样会导致数据多的时候输出超时,不是很建议这样做。但是像我这样新手学习的过程,循环比栈是要先接触的,所以可以先尝试这样看看,下面是我画的大致流程图。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApp7
{
class DemoMain
{
static void Main(string[] args)
{
// 输入
string input = Console.ReadLine();
// 传入动态数组,并设置为字符char类型
ArrayList arr = new ArrayList(input.ToCharArray());
//从第二个开始遍历,第一个没有比对的对象
int i = 1;
while (i < arr.Count) {
//当遍历到的元素与前一个相等时,我们给循环赋初值,重新遍历
if (arr[i].ToString() == arr[i - 1].ToString())
{
arr.RemoveAt(i); // c#删除动态数组元素的方法
arr.RemoveAt(i - 1);
i = 1;
}
else {
i++; // 不等的时候递增
}
}
if(arr.Count == 0)
{
Console.WriteLine(0); // 当没有剩下的元素时输出0
}
else
{
foreach(char res in arr) Console.Write(res); // 直接输出动态数组会输出类型,所以把它放进一个list输出
}
Console.ReadKey(); //等待键盘操作
}
}
}
思路2:利用栈来解决,栈遵循后入先出原则
- 首先我们将第一个数放入栈中,然后第二个值与栈顶元素比对,如果一样就将栈顶元素出栈,不一样就入栈。
- 入栈后的最后一个元素会成为栈顶元素,继续与它的下一个元素比对。顺带一提,栈的优点就是读取速度快,所以这里不会出现超时问题。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DemoStack
{
class DemoMain
{
static void Main(string[] args)
{
//Push(object obj) 向栈中添加元素,也称入栈
//object Peek() 用于获取栈顶元素的值,但不移除栈顶元素的值
//object Pop() 用于移除栈顶元素的值,并移除栈顶元素
//Clear() 从 Stack 中移除所有的元素
//Contains(object obj) 判断某个元素是否在 Stack 中
//object[] ToArray() 复制 Stack 到一个新的数组中
// 输入
string input = Console.ReadLine();
// 建栈
Stack<char> st = new Stack<char>();
//第一个元素入栈
st.Push(input[0]);
//ArrayList arr = new ArrayList(input);
int i = 1;
while (i < input.Length)
{
//从第二个元素开始遍历,满足条件就出栈
if (st.Count!=0 && st.Peek()== input[i])
{
st.Pop();
i++;
}
else
{
//不满足的话接下来的一个元素入栈,放在栈顶和它之后的元素比较
st.Push(input[i]);
i++; }
}
if (st.Count == 0)
{
Console.Write(0);
}
else
{
string res = "";
while (st.Count != 0)
{
res = st.Peek() + res;
st.Pop(); //每取一个就删除一个,否则会一直循环
}
Console.Write(res);
}
Console.ReadKey();
}
}
}
}
感谢观看,各位有意向走C#这个方向的可以加入我新创的C#新手交流群,互帮互助,互相学习。学习群号781462455,或者扫码进入。