[力扣] 算法 208 (C#)

208. 实现 Trie (前缀树)

public class Trie
{
    class Node
    {
        public readonly Node[] child = new Node[26];
        public bool isEnd;

        public void Insert(CharEnumerator chars)
        {
            ref var node = ref child[chars.Current - 'a'];
            if (node == null)
                node = new Node();
            if (chars.MoveNext())
                node.Insert(chars);
            else
                node.isEnd = true;
        }
    }

    Node root = new Node();

    public Trie() { root.isEnd = true; }

    public void Insert(string word)
    {
        if (word == string.Empty)
            return;
        var itor = word.GetEnumerator();
        itor.MoveNext();
        root.Insert(itor);
    }

    public bool Search(string word)
    {
        var node = root;
        foreach (var ch in word)
        {
            ref var next = ref node.child[ch - 'a'];
            if (next == null)
                return false;
            node = next;
        }
        return node.isEnd;
    }

    public bool StartsWith(string prefix)
    {
        var node = root;
        foreach (var ch in prefix)
        {
            ref var next = ref node.child[ch - 'a'];
            if (next == null)
                return false;
            node = next;
        }
        return true;
    }
}

[力扣] 算法 150 (C#)

150. 逆波兰表达式求值

public class Solution
{
    public int EvalRPN(string[] tokens)
    {
        var stack = new Stack<int>();
        foreach (var token in tokens)
        {
            switch (token)
            {
                case var add when add == "+":
                    stack.Push(stack.Pop() + stack.Pop());
                    break;
                case var minus when minus == "-":
                    stack.Push(-stack.Pop() + stack.Pop());
                    break;
                case var mul when mul == "*":
                    stack.Push(stack.Pop() * stack.Pop());
                    break;
                case var div when div == "/":
                    var top = stack.Pop();
                    stack.Push(stack.Pop() / top);
                    break;
                default:
                    stack.Push(int.Parse(token));
                    break;
            }
        }
        return stack.Pop();
    }
}

[力扣] 算法 59 (C#)

59. 螺旋矩阵 II

public class Solution {
    public int[][] GenerateMatrix(int n) {
        var ret = new int[n][];
        for (var i = 0; i < ret.Length; i++)
            ret[i] = new int[n];
        var loc = (x:0, y:0);
        var dir = (x:0, y:1);
        for(var i = 0; i < n * n; i++)
        {
            ret[loc.x][loc.y] = i + 1;
            var next = (x:loc.x + dir.x, y:loc.y + dir.y);
            if(next.x < 0 || next.y<0||next.x == n || next.y == n || ret[next.x][next.y] != 0)
            {
                dir = (dir.y, -dir.x);
                next = (x: loc.x + dir.x, y: loc.y + dir.y);
            }
            loc = next;
        }
        return ret;
    }
}

[力扣] 算法 227 (C#)

227. 基本计算器 II

直接拿 224 的代码改(尽管这道题不用处理括号)

public class Solution
{
    public int Calculate(string s) => Bar(Foo(s));

    List<IConvertible> Foo(string s)
    {
        var stack = new Stack<char>(s.Length);// ( + - * / only
        var ret = new List<IConvertible>(s.Length);
        for (var i = 0; i < s.Length; i++)
        {
            var ch = s[i];
            switch (ch)
            {
                case '(':
                    stack.Push('(');
                    break;
                case ')':
                    char top;
                    while ((top = stack.Pop()) != '(')
                        ret.Add(top);
                    break;
                case '+':
                case '-':
                    while (stack.Count > 0 && stack.Peek() != '(')
                        ret.Add(stack.Pop());
                    stack.Push(ch);
                    break;
                case '*':
                case '/':
                    while (stack.Count > 0 && (stack.Peek() == '*' || stack.Peek() == '/'))
                        ret.Add(stack.Pop());
                    stack.Push(ch);
                    break;
                case ' ':
                    break;
                default:// 0 ~ 9
                    long num = ch - '0';
                    for (; i + 1 < s.Length && s[i + 1] >= '0' && s[i + 1] <= '9'; i++)
                    {
                        num *= 10;
                        num += s[i + 1] - '0';
                    }
                    ret.Add(num);
                    break;
            }
        }
        while (stack.Count > 0)
            ret.Add(stack.Pop());
        return ret;
    }

    int Bar(List<IConvertible> foo)
    {
        var stack = new Stack<long>();
        foreach (var f in foo)
        {
            switch (f)
            {
                case '+':
                    stack.Push(stack.Pop() + stack.Pop());
                    break;
                case '-':
                    if (stack.Count > 1)
                        stack.Push(-(stack.Pop() - stack.Pop()));
                    else
                        stack.Push(-stack.Pop());
                    break;
                case '*':
                    stack.Push(stack.Pop() * stack.Pop());
                    break;
                case '/':
                    var got = stack.Pop();
                    stack.Push(stack.Pop() / got);
                    break;
                default:// long
                    stack.Push((long)f);
                    break;
            }
        }
        return (int)stack.Peek();
    }
}

[力扣] 算法 224 (C#)

224. 基本计算器

public class Solution
{
    public int Calculate(string s) => Bar(Foo(s));

    List<IConvertible> Foo(string s)
    {
        var stack = new Stack<char>(s.Length);// ( + - only
        var ret = new List<IConvertible>(s.Length);
        for (var i = 0; i < s.Length; i++)
        {
            var ch = s[i];
            switch (ch)
            {
                case '(':
                    stack.Push('(');
                    break;
                case ')':
                    char top;
                    while ((top = stack.Pop()) != '(')
                        ret.Add(top);
                    break;
                case '+':
                case '-':
                    while (stack.Count > 0 && stack.Peek() != '(')
                        ret.Add(stack.Pop());
                    stack.Push(ch);
                    break;
                case ' ':
                    break;
                default:// 0 ~ 9
                    long num = ch - '0';
                    for (; i + 1 < s.Length && s[i + 1] >= '0' && s[i + 1] <= '9'; i++)
                    {
                        num *= 10;
                        num += s[i + 1] - '0';
                    }
                    ret.Add(num);
                    break;
            }
        }
        while (stack.Count > 0)
            ret.Add(stack.Pop());
        return ret;
    }

    int Bar(List<IConvertible> foo)
    {
        var stack = new Stack<long>();
        foreach (var f in foo)
        {
            switch (f)
            {
                case '+':
                    stack.Push(stack.Pop() + stack.Pop());
                    break;
                case '-':
                    if (stack.Count > 1)
                        stack.Push(-(stack.Pop() - stack.Pop()));
                    else
                        stack.Push(-stack.Pop());
                    break;
                default:// long
                    stack.Push((long)f);
                    break;
            }
        }
        return (int)stack.Peek();
    }
}

参考资料

[力扣] 算法 263 (C#)

263. 丑数

Plan A

public class Solution
{
    public bool IsUgly(int n)
    {
        if (n == 0)
            return false;
        if (n == 1)
            return true;
        if ((n % 2) == 0)
            return IsUgly(n / 2);
        if ((n % 3) == 0)
            return IsUgly(n / 3);
        if ((n % 5) == 0)
            return IsUgly(n / 5);
        return false;
    }
}

Plan B,易扩展

public class Solution
{
    public bool IsUgly(int n)
    {
        if (n == 0)// 这道题也可以判断 n < 1
            return false;
        Bar(ref n, 2, 3, 5);
        return n == 1;
    }

    void Foo(ref int n, int a)
    {
        while ((n % a) == 0)
            n /= a;
    }

    void Bar(ref int n, params int[] @as)
    {
        foreach (var a in @as)
            Foo(ref n, a);
    }
}