面试精选题

两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。

public class Solution {
    public int[] TwoSum(int[] nums, int target)
        {
            Dictionary<int, int> d = new Dictionary<int, int>();
            for(int i=0;i<nums.Length;i++)
            {
                if(d.ContainsKey(target-nums[i]))
                {
                    return new int[] { d[target-nums[i]],i };
                }
                else
                {
                    d[nums[i]] = i;
                }
            }
            return new int[] { 0, 0 };
        }
}

两数相加

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     public int val;
 *     public ListNode next;
 *     public ListNode(int val=0, ListNode next=null) {
 *         this.val = val;
 *         this.next = next;
 *     }
 * }
 */
public class Solution {

    public ListNode AddTwoNumbers(ListNode l1, ListNode l2) {
        int nSum; //列表对应节点的和
            ListNode resNode = new ListNode(0); //返回模型
            ListNode curNode = resNode; //当前计算模型
            int nAdd = 0;  //进位
            do
            {
                int n1 = l1 == null ? 0 : l1.val;
                int n2 = l2 == null ? 0 : l2.val;
                nSum = n1 + n2 + nAdd; //列表对应节点的和
                nAdd = nSum / 10;   //十位
                curNode.next = new ListNode(nSum % 10);
                curNode = curNode.next;
                l1 = l1.next;
                l2 = l2.next;

            } while (l1 != null || l2 != null || nAdd != 0);
            return resNode.next;//去除初始化的0
    }

}

无重复字符的最长子串

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

public class Solution {
    public int LengthOfLongestSubstring(string s) {
        if (s.Length < 2) return s.Length;

        var left = 0;
        var right = 0;
        var maxlen = 0;

        var charSet = new HashSet<char>();
        
        while (right < s.Length) {
            if (charSet.Contains(s[right]) == false) {
                charSet.Add(s[right++]);
                maxlen = Math.Max(maxlen, right - left);
            } else {
                charSet.Remove(s[left++]);
            }
        }

        return maxlen;
    }
}

寻找两个正序数组的中位数

给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
算法的时间复杂度应该为 O(log (m+n)) 。

public double FindMedianSortedArrays(int[] A, int[] B) {
        //确保A长度小于等于B
        if (A.Length > B.Length)
        {
            int[] temp = A;
            A = B;
            B = temp;
        }
        int iStart = 0;
        int iEnd = A.Length;
        //正常范围内
        while (iStart <= iEnd)
        {
            int i = (iStart + iEnd) / 2;//取中间索引 二分查找法
            //在索引i位置将A切为两半,A左半部分长度为i,右半部分为A.length-i;
            //在索引j位置将B切为两半,B左半部分长度为j,右半部分长度为B.length-j;
            //将A左半部分与B左半部分相加,A右半部分与B右半部分相加 有i+j=A.length-i+B.length-j 或A.length-i+B.length-j+1;
            //整合得到j的表达式
            int j = (A.Length + B.Length + 1 - 2 * i) / 2;
            //找到中位数时存在以下不等式关系
            //此时i偏小 继续二分查找并增大i
            if (i < iEnd && B[j - 1] > A[i])
            {
                iStart = i + 1;
            }
            //i偏大
            else if (i > iStart && A[i - 1] > B[j])
            {
                iEnd = i - 1;
            }
            //满足条件
            else
            {
                //边界值
                int maxLeft = 0;
                if (i == 0)
                {
                    maxLeft = B[j - 1];
                }
                else if (j == 0)
                {
                    maxLeft = A[i - 1];
                }
                else
                {
                    maxLeft = Math.Max(A[i - 1], B[j - 1]);
                }
                //奇数情况
                if ((A.Length + B.Length) % 2 == 1)
                {
                    return maxLeft;
                }
                //边界值
                int minRight = 0;
                if (i == A.Length)
                {
                    minRight = B[j];
                }
                else if (j == B.Length)
                {
                    minRight = A[i];
                }
                else
                {
                    minRight = Math.Min(B[j], A[i]);
                }
                //偶数情况
                return (maxLeft + minRight) / 2.0;
            }
        }
        return 0.0;
    }

最长回文子串

给你一个字符串 s,找到 s 中最长的回文子串。

  public string LongestPalindrome(string s)
    {
        string result = "";
        int n = s.Length;
        int end = 2 * n - 1;
        for (int i = 0; i < end; i ++)
        {
            double mid = i / 2.0;
            int p = (int)(Math.Floor(mid));
            int q = (int)(Math.Ceiling(mid));
            while (p >= 0 && q < n)
            {
                if (s[p] != s[q]) break;
                p--; q++;
            }
            int len = q - p - 1;
            if (len > result.Length)
                result = s.Substring(p + 1, len);
        }
        return result;
    }

整数反转

给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。

public class Solution {
    public int Reverse(int x) {
        int rev = 0;
        while (x != 0) {
            if (rev < int.MinValue / 10 || rev > int.MaxValue / 10) {
                return 0;
            }
            int digit = x % 10;
            x /= 10;
            rev = rev * 10 + digit;
        }
        return rev;
    }
}

字符串转换整数 (atoi)

请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)

public class Solution 
{
    public int MyAtoi(string s) 
    {
        // 为空直接返回
        if(s.Length==0) return 0;
        // 正负号
        int plus=1;
        // 结果
        int result=0;
        // 去空格
        if(s[0]==' ')
        {
            for(int i=0;i<s.Length;i++)
            {
                if(s[i]!=' ') 
                {
                    s=s[i..s.Length];
                    break;
                }
            }
        }
        // 判断正负号
        if(s[0]=='-')
        {
            plus=-1;
            s=s[1..s.Length];
        }
        else if(s[0]=='+') s=s[1..s.Length];
        // 逐位判断
        for(int i=0;i<s.Length;i++)
        {
            // 数字
            if(s[i]>='0'&&s[i]<='9')
            {
                // 判断是否溢出
                if(plus==1)
                {
                    if(result>int.MaxValue/10) return int.MaxValue;
                    if(result==int.MaxValue/10 && s[i]>='7')  return int.MaxValue;
                }
                else
                {
                    if(result>int.MaxValue/10) return int.MinValue;
                    if(result==int.MaxValue/10 && s[i]>='8')  return int.MinValue;
                }
                // 更新结果
                result=result*10+(s[i]-'0');
            }
            // 非数字,直接返回结果
            else return result*plus;
        }
        // 判断完毕,返回结果
        return result*plus;
    }
}

正则表达式匹配

给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 ‘’ 的正则表达式匹配。
‘.’ 匹配任意单个字符
'
’ 匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。

public class Solution {
    public bool IsMatch(string s, string p)//m x n 动态规划法 求正则表达式匹配算法 *号 +号
    {
        int m = s.Length;
        int n = p.Length;

        bool[,] f = new bool[m + 1, n + 1];//横竖多一个格子
        f[0, 0] = true;
        for (int i = 0; i <= m; ++i)//i 代表当前行,j代表当前列 s[i-1]代表 s[j-1]
        {
            for (int j = 1; j <= n; ++j)//逐行计算,从第二列 (基本上如果有一行没有出现真,可以返回假)
            {
                if (p[j - 1] == '*')//如果当前列是星
                {
                    if (j > 1)
                    {
                        f[i, j] = f[i, j - 2];//当前格先按照星左边的左边格匹配hot(代表0个的时候)
                        if (UnitMatche(s, p, i, j - 1))//如果星前面能和本行字符匹配
                        {
                            f[i, j] = f[i, j] || f[i - 1, j];//本格=本格|正上方
                        }
                    }
                }
                else//如果前一个不是星
                {
                    if (UnitMatche(s, p, i, j))//如果本格匹配
                    {
                        f[i, j] = f[i - 1, j - 1];//赋值为左上方匹配
                    }
                }
            }
        }
        return f[m, n];//返回最后一格
    }

    public bool UnitMatche(string s, string p, int i, int j)//只看一个单元格的匹配情况
    {
        if (i == 0) return false;//最上一行不匹配,只有0,0点
        if (p[j - 1] == '.') return true;//任何字符和点匹配成功
        return s[i - 1] == p[j - 1];//返回相等匹配
    }
}

盛最多水的容器

给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

public class Solution {
    public int MaxArea(int[] height) {
        int l = 0, r = height.Length - 1, ans = -1, curr = -1;
        while (l <= r) {
            curr = (r - l) * Math.Min(height[l], height[r]);
            ans = Math.Max(curr, ans);
            if (height[l] < height[r]) l++;
            else r--;
        }
        return ans;
    }
}

最长公共前缀

编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”。

//执行用时: 116 ms;内存消耗: 24.5 MB
public class Solution {
    public string LongestCommonPrefix(string[] strs) {
        if (strs.Length==0){
            return "";
        }
        
        for (int i = 0; i < strs[0].Length; ++i) {
            char c = strs[0][i];
            for (int j = 1; j < strs.Length; ++j) {
                if (i == strs[j].Length || strs[j][i] != c) {
                    return strs[0].Substring(0, i);
                }
            }
        }
        return strs[0];
    }
}

三数之和

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。

public IList<IList<int>> ThreeSum(int[] nums)
    {
        IList<IList<int>> result = new List<IList<int>>();
        int len = nums.Length;
        if (len < 3) return result;
        Array.Sort(nums);
        for (int i = 0; i < len - 2; i++)
        {
            if (nums[i] > 0) break;
            if (i > 0 && nums[i] == nums[i - 1]) continue; // 去重
            int left = i + 1;
            int right = len - 1;
            while (left < right)
            {
                int sum = nums[i] + nums[left] + nums[right];
                if (sum == 0)
                {
                    result.Add(new List<int>() { nums[i], nums[left], nums[right] });
                    while (left < right && nums[left] == nums[left + 1]) left++; // 去重
                    while (left < right && nums[right] == nums[right - 1]) right--; // 去重
                    left++;
                    right--;
                }
                else if (sum < 0) left++;
                else if (sum > 0) right--;
            }
        }
        return result;
    }

删除链表的倒数第 N 个结点

public ListNode RemoveNthFromEnd(ListNode head, int n) {
                ListNode preHead = new ListNode();
                preHead.next = head;
                ListNode pre, end;
                pre = preHead;
                end = preHead;

                for (var i = 0; i < n; i++)
                {
                    end = end.next;
                }
                while (end.next != null)
                {
                    pre = pre.next;
                    end = end.next;
                }

                // Remove
                pre.next = pre.next.next;               

                return preHead.next;
    }

有效的括号

给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。

public class Solution {
    public bool IsValid(string s) {
        Stack<char> st = new Stack<char>();
        for(int i = 0;i < s.Length;i++)
        {
            if(s[i] == '(' || s[i] == '{' || s[i] == '[')
            {
                st.Push(s[i]);//如果是左括号,入栈
            }
            else if(s[i] == ')')
            {
                if(st.Count != 0 && st.Peek() =='(')
                {
                    st.Pop();//如果是右小括号且栈不为空,判断栈顶元素是否为左小括号
                }
                else
                {
                    return false;//是,栈顶左括号出栈;否,右括号无法配对,返回false
                }
            }
            else if(s[i] == '}')
            {
                if(st.Count != 0 && st.Peek() =='{')
                {
                    st.Pop();
                }
                else
                {
                    return false;
                }
            }
            else if(s[i] == ']')
            {
                if(st.Count != 0 && st.Peek() =='[')
                {
                    st.Pop();
                }
                else
                {
                    return false;
                }
            }
        }
        return st.Count == 0;//如果栈为空,括号全部配对完,返回true
    }
}

合并两个有序链表

public class Solution {
    public ListNode MergeTwoLists(ListNode l1, ListNode l2) {
        ListNode prehead = new ListNode(-1);

        ListNode prev = prehead;
        while (l1 != null && l2 != null) {
            if (l1.val <= l2.val) {
                prev.next = l1;
                l1 = l1.next;
            } else {
                prev.next = l2;
                l2 = l2.next;
            }
            prev = prev.next;
        }

        // 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可
        prev.next = l1 == null ? l2 : l1;

        return prehead.next;
    }
}

括号生成

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

public class Solution {

    public IList<string> output = new List<string>();

    public void SetGenerate(string str,int left,int right){
        //若left和right 都为 0 则输出字符串
        if(left == 0 && right == 0){
            output.Add(str);
        }
        if(left > 0){
            string leftstr = str + "(";
            SetGenerate(leftstr,left-1,right+1);
        }
        if(right > 0){
            string rightstr = str + ")";
            SetGenerate(rightstr,left,right-1);
        }
    }

    public IList<string> GenerateParenthesis(int n) {
        SetGenerate("",n,0);//left需要 n 个,right则看字符串中的"("而定
        return output;
    }

}

合并K个升序链表

给你一个链表数组,每个链表都已经按升序排列。

请你将所有链表合并到一个升序链表中,返回合并后的链表。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     public int val;
 *     public ListNode next;
 *     public ListNode(int val=0, ListNode next=null) {
 *         this.val = val;
 *         this.next = next;
 *     }
 * }
 */
public class Solution {
    public ListNode MergeKLists(ListNode[] lists) {
        if(lists == null || lists.Length == 0) {
            return null;
        }

        return MergeKLists(lists, 0, lists.Length-1);
    }

    private ListNode MergeKLists(ListNode[] lists, int left, int right) {
        if(left == right) {
            return lists[left];
        }
        int mid = left + (right-left)/2;
        ListNode l1 = MergeKLists(lists, left, mid);
        ListNode l2 = MergeKLists(lists, mid+1, right);

        return MergeTwoLists(l1, l2);
    }

    private ListNode MergeTwoLists(ListNode l1, ListNode l2) {
        if(l1 == null) {
            return l2;
        }
        if(l2 == null) {
            return l1;
        }

        ListNode dummy = new ListNode();
        ListNode p1 = l1, p2 = l2, cur = dummy;
        while(p1 != null && p2 != null) {
            if(p1.val < p2.val) {
                cur.next = p1;
                cur = cur.next;
                p1 = p1.next;
            } else {
                cur.next = p2;
                cur = cur.next;
                p2 = p2.next;
            }
        }

        cur.next = p1 == null ? p2 : p1;

        return dummy.next;
    }
}

删除有序数组中的重复项

给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。

不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

public class Solution {
    public int RemoveDuplicates(int[] nums) {
        if(nums.Length == 0){return 0;}
        int slow = 0, fast = 1;
        while(fast < nums.Length){
            if(nums[fast] != nums[slow]){
                slow = slow + 1;
                nums[slow] = nums[fast];
            }
            fast = fast + 1;
        }
        return slow + 1;
    }
}

两数相除

给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。

返回被除数 dividend 除以除数 divisor 得到的商。

整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2

public class Solution {
    public int Divide(int dividend, int divisor) {
        // 考虑被除数为最小值的情况
        if (dividend == int.MinValue) {
            if (divisor == 1) {
                return int.MinValue;
            }
            if (divisor == -1) {
                return int.MaxValue;
            }
        }
        // 考虑除数为最小值的情况
        if (divisor == int.MinValue) {
            return dividend == int.MinValue ? 1 : 0;
        }
        // 考虑被除数为 0 的情况
        if (dividend == 0) {
            return 0;
        }
        
        // 一般情况,使用二分查找
        // 将所有的正数取相反数,这样就只需要考虑一种情况
        bool rev = false;
        if (dividend > 0) {
            dividend = -dividend;
            rev = !rev;
        }
        if (divisor > 0) {
            divisor = -divisor;
            rev = !rev;
        }
        
        int left = 1, right = int.MaxValue, ans = 0;
        while (left <= right) {
            // 注意溢出,并且不能使用除法
            int mid = left + ((right - left) >> 1);
            bool check = quickAdd(divisor, mid, dividend);
            if (check) {
                ans = mid;
                // 注意溢出
                if (mid == int.MaxValue) {
                    break;
                }
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }

        return rev ? -ans : ans;
    }

    // 快速乘
    public bool quickAdd(int y, int z, int x) {
        // x 和 y 是负数,z 是正数
        // 需要判断 z * y >= x 是否成立
        int result = 0, add = y;
        while (z != 0) {
            if ((z & 1) != 0) {
                // 需要保证 result + add >= x
                if (result < x - add) {
                    return false;
                }
                result += add;
            }
            if (z != 1) {
                // 需要保证 add + add >= x
                if (add < x - add) {
                    return false;
                }
                add += add;
            }
            // 不能使用除法
            z >>= 1;
        }
        return true;
    }
}

搜索旋转排序数组

整数数组 nums 按升序排列,数组中的值 互不相同 。

在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], …, nums[n-1], nums[0], nums[1], …, nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。

给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。

public class Solution {
    public int Search(int[] nums, int target) {
        int i;
        for(i=0;i<nums.Length-1;i++)
            if(nums[i]>nums[i+1])
                break;
        if(nums[0]>target)
            for(int j=i+1;j<nums.Length;j++)
            {
                if(nums[j]==target)
                return(j);
            }
        else
        {
            for(int j=0;j<i+1;j++){
                if(nums[j]==target)
                return(j);
            }
        }
        return(-1);
    }
}

在排序数组中查找元素的第一个和最后一个位置

public class Solution {
    public int[] SearchRange(int[] nums, int target) {
              int[] res = new int[] { -1,-1};
            int left = 0;
            int right = nums.Length;
            while (left<=right)
            {
                int mid = left + (right - left) / 2;
                if (mid>nums.Length-1)
                {
                    return res;
                }
                if (nums[mid]==target)
                {
                    for (int i = mid; i < nums.Length; i++)
                    {
                        if (nums[i]==target)
                        {
                            res[1] = i;
                        }
                    }
                    for (int i = mid; i >= 0; i--)
                    {
                        if (nums[i] == target)
                        {
                            res[0] = i;
                        }
                    }
                    return res;
                }
                else if (nums[mid]<target)
                {
                    left = mid + 1;
                }
                else if (nums[mid]>target)
                {
                    right = mid - 1;
                }
            }

            return res;
    }
}

缺失的第一个正数

给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。

请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。
在这里插入图片描述

//c++代码
class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        int n = nums.size();
        for (int& num: nums) {
            if (num <= 0) {
                num = n + 1;
            }
        }
        for (int i = 0; i < n; ++i) {
            int num = abs(nums[i]);
            if (num <= n) {
                nums[num - 1] = -abs(nums[num - 1]);
            }
        }
        for (int i = 0; i < n; ++i) {
            if (nums[i] > 0) {
                return i + 1;
            }
        }
        return n + 1;
    }
};

接雨水(注重思路)

在这里插入图片描述

public class Solution {
    public int Trap(int[] height) {
        // 存柱子高度index
        Stack<int> st = new Stack<int>();
        int sum = 0;
        for(int i = 0; i < height.Length; i++){
            while(st.Count != 0 && height[i] > height[st.Peek()]){
                int mid = st.Pop();
                // 左边没柱子了,直接跳出
                if(st.Count == 0) break;
                // 比如 0 1 2 3 对应 1 0 0 1, 1 和 1 之间有 0 0 两个数,则间隔为 3 - 0 - 1 = 2
                int distance = i - st.Peek() - 1;
                // 最小高度
                int minHeight = Math.Min(height[st.Peek()], height[i]) - height[mid];
                sum += distance * minHeight;
            }
            st.Push(i);
        }
        return sum;
    }
}

最大子数组和

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
子数组 是数组中的一个连续部分。

public class Solution {
    public int MaxSubArray(int[] nums) {
        int pre = 0, maxAns = nums[0];
        foreach (int x in nums) {
            pre = Math.Max(pre + x, x);
            maxAns = Math.Max(maxAns, pre);
        }
        return maxAns;
    }
}

跳跃游戏

给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。

数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个下标。

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int n = nums.size();
        int rightmost = 0;
        for (int i = 0; i < n; ++i) {
            if (i <= rightmost) {
                rightmost = max(rightmost, i + nums[i]);
                if (rightmost >= n - 1) {
                    return true;
                }
            }
        }
        return false;
    }
};

爬楼梯

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

public class Solution {
    public int ClimbStairs(int n) {
        // 动态规划
        int p = 0, q = 0, r = 1;
        for (int i = 1; i <= n; ++i) {
            p = q;
            q = r;
            r = p + q;
        }
        return r;
	}
}

二叉树的中序遍历

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left;
 *     public TreeNode right;
 *     public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
public class Solution {
    public IList<int> InorderTraversal(TreeNode root) {
        List<int> list = new List<int>();
        Stack<TreeNode> stack = new Stack<TreeNode>();
        while(root!=null || stack.Count != 0)
        {
            while(root!=null)
            {
                stack.Push(root);
                root = root.left;
            }
            root = stack.Pop();
            list.Add(root.val);
            root = root.right;
        }
        return list;
    }
}

验证二叉搜索树

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

节点的左子树只包含 小于 当前节点的数。
节点的右子树只包含 大于 当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left;
 *     public TreeNode right;
 *     public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
public class Solution {
    public bool IsValidBST(TreeNode root) {
        return check(root,null,null);
    }

    public bool check(TreeNode root,int? min,int? max){
        if(null == root) return true;
        if((null != min) && (root.val <= min)) return false;
        if((null != max) && (root.val >= max)) return false;
        return check(root.left,min,root.val) && check(root.right,root.val,max);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值