算法比较C#
我目前正在看一些典型的面试问题,以便让我有一个正确的心态。 我试图提出自己的问题解决方案,而不是试图记住给定的解决方案 问题是,我不确定我的解决方案是否最优,或者在设计中是否存在我没有看到的重大缺陷 下面是我为基本的“这个字符串唯一吗”问题提出的解决方案之一,比如检查字符串中的所有字符是否唯一算法比较C#,c#,performance,algorithm,C#,Performance,Algorithm,我目前正在看一些典型的面试问题,以便让我有一个正确的心态。 我试图提出自己的问题解决方案,而不是试图记住给定的解决方案 问题是,我不确定我的解决方案是否最优,或者在设计中是否存在我没有看到的重大缺陷 下面是我为基本的“这个字符串唯一吗”问题提出的解决方案之一,比如检查字符串中的所有字符是否唯一 public static bool IsUnique(string str) { bool isUnique = true; for (int i = 0; i
public static bool IsUnique(string str)
{
bool isUnique = true;
for (int i = 0; i < str.Length; i++)
{
if (str.LastIndexOf(str.ElementAt(i)) != i)
{
isUnique = false;
break;
}
}
return isUnique;
}
公共静态bool是唯一的(字符串str)
{
bool isUnique=true;
对于(int i=0;i
有人对这段代码是否是最优的,是否具有可接受的时间和空间复杂度提出了建议吗?为了回答这个问题,我将引用Big-O符号来表示算法的复杂度。提高效率的诀窍是实现解决问题的最小大O度量,然后尝试复制该效率 通过逻辑地考虑算法,您可以得出一些效率事实:要检查所有字符是否唯一,您需要计算所有字符。所以这是一个O(n)遍历字符串的保证,我怀疑你会很容易得到比这更有效的。现在,你能在O(n)或O(2n)时间内自己解决它吗?如果是这样的话,那就相当不错了,因为您的算法处于线性时间段,并且将以线性进行缩放(对于较大的字符串输入,稳定地变慢) 您当前的算法在字符串上循环,然后针对每个字符,再次在字符串上迭代以进行比较并找到相等的字符。这使得该算法成为一个n次遍历,其中每次访问本身执行一个n次遍历,因此是一个O(n^2)算法。这就是所谓的多项式时间算法,它不是很好,因为它不是线性伸缩的;它以多项式方式缩放。这意味着您的算法在输入较大时会变得慢得多,这是一件坏事 一个快速的改变是,在字符串+1中的当前索引处开始比较一个等效字符,使其稍微更有效。。。您知道所有以前选中的字符都是唯一的,所以您只关心将来的字符。这将成为一个n遍历,其中每次访问都从当前点进行子字符串遍历(遍历字符串时所做的工作更少),但这也是一个O(n^2)算法,因为它在外循环时间的平方内运行。与以前一样,这也是一种多项式时间算法,但效率稍高。然而,如果投入更大,它的规模仍然会很糟糕 考虑避免重复迭代的替代方法。这些通常是以牺牲内存为代价的,但它们是实用的。我知道我会如何解决这个问题,但告诉你我的答案无助于你学习 编辑:根据您的要求,我将分享我的答案 我会通过拥有一个哈希集来实现这一点,我会将每个访问的字符加载到哈希集中。HashSet查找和添加大约是一个O(1)操作。Add方法的优点在于,如果它添加了值,则返回true;如果值已经存在,则返回false(这是决定算法结果的条件)。因此,我的建议是:
var hashSet = new HashSet<char>();
foreach (char c in myString)
{
if (!hashSet.Add(c))
{
return false;
}
}
return true;
var hashSet=new hashSet();
foreach(myString中的字符c)
{
如果(!hashSet.Add(c))
{
返回false;
}
}
返回true;
优点:O(n)线性算法
缺点:用于哈希集的额外内存
EDIT2:每个人都喜欢廉价的LINQ把戏,所以这里有另一种方法
var hashSet = new HashSet<char>();
return myString.Any(c => !hashSet.Add(c));
var hashSet=new hashSet();
返回myString.Any(c=>!hashSet.Add(c));
与使用线性查找时间O(n)查找字符串中的字符相比,使用哈希集的查找时间O(1)恒定,因此效率更高:
公共静态bool AreCharsUnique(字符串str)
{
var charset=new HashSet();
foreach(str中的字符c){
if(字符集包含(c)){
返回false;
}否则{
添加(c);
}
}
返回true;
}
可能是因为这个问题似乎离题了,因为它是关于而不是代码修复的。请使用str[i]
。考虑使用HasSt集。取决于你要做什么-微优化与可读性。可读性,您可能不需要使用s.Length==s.Distinct().Count()
,但这可能不是微优化的。即使这只使用1作为循环,它仍然是一个O(n^2)算法。这是因为elementAt
和LastIndexOf
是O(n)。试着把这些字符放进某种字典里,检查是否有冲突不要给他们答案:他们想知道如何判断他们何时得到了正确答案,而不是正确答案是什么。谢谢你的答案大卫。我也在沿着这些思路思考。我发现很难找到一个复杂度很高的解决方案,另外还要注意的是,算法中不能使用其他数据结构。是的,在当前索引之后启动索引1,以避免再次遍历整个字符串,这更有意义。O(n^2)是多项式。O(2^n)是指数的。而且,阶乘是指数的,所以它比O(n^2)差得多,不是更好。啊,非常好,因为哈希集中不允许有重复项。。快乐的日子。
public static bool AreCharsUnique(string str)
{
var charset = new HashSet<char>();
foreach (char c in str) {
if (charset.Contains(c)) {
return false;
} else {
charset.Add(c);
}
}
return true;
}