Category Archives: LeetCode

LeetCode Fraction Addition and Subtraction

LeetCode Fraction Addition and Subtraction Given a string representing an expression of fraction addition and subtraction, you need to return the calculation result in string format. The final result should be irreducible fraction. If your final result is an integer, say 2, you need to change it to the format of fraction that has denominator 1. So in this case, 2 should be converted to 2/1. Example 1:

Input:"-1/2+1/2"
Output: "0/1"
Example 2:
Input:"-1/2+1/2+1/3"
Output: "1/3"
Example 3:
Input:"1/3-1/2"
Output: "-1/6"
Example 4:
Input:"5/3+1/3"
Output: "2/1"
Note:
  1. The input string only contains '0' to '9', '/', '+' and '-'. So does the output.
  2. Each fraction (input and output) has format ±numerator/denominator. If the first input fraction or the output is positive, then '+' will be omitted.
  3. The input only contains valid irreducible fractions, where the numerator and denominator of each fraction will always be in the range [1,10]. If the denominator is 1, it means this fraction is actually an integer in a fraction format defined above.
  4. The number of given fractions will be in the range [1,10].
  5. The numerator and denominator of the final result are guaranteed to be valid and in the range of 32-bit int.

给定一个只包含+-/的运算字符串,要求求出这个字符串的值,并且用最简分数的形式表示。 参考这篇博客,没什么技巧,就是用代码模拟手算的过程。首先求出所有分母的最小公倍数,然后通分,使得所有数的分母都相同,最后把所有通分过的分子加起来,得到结果。最最后一步就是把分子和分母约分。 这些步骤中涉及到求最小公倍数和最大公约数。最大公约数的求法gcd是必须掌握的,另外再根据gcd(x,y)*lcm(x,y)=x*y的性质,可以求到最小公倍数lcm(x,y)。 代码如下: [cpp] class Solution { private: int gcd(int x, int y) { while (y) { int tmp = x % y; x = y; y = tmp; } return x; } int lcm(int x, int y) { return x * y / gcd(x, y); } public: string fractionAddition(string expression) { vector<int> num, denom; // 分子,分母 expression += "+"; // 哨兵 int i = 0, j = 0; bool isnum = true; for (j = 0; j < expression.size(); ++j) { if (j != 0 && (expression[j] == ‘/’ || expression[j] == ‘-‘ || expression[j] == ‘+’)) { int one = atoi(expression.substr(i, j – i).c_str()); if (isnum)num.push_back(one); else denom.push_back(one); isnum = !isnum; if (expression[j] == ‘/’) i = j + 1; else i = j; } } int fm = 1; for (int i = 0; i < denom.size(); ++i)fm = lcm(fm, denom[i]); int fz = 0; for (int i = 0; i < num.size(); ++i)fz += num[i] * (fm / denom[i]); int g = 0; if (fz < 0) g = gcd(-fz, fm); else g = gcd(fz, fm); return to_string(fz / g) + "/" + to_string(fm / g); } }; [/cpp] 本代码提交AC,用时3MS。]]>

LeetCode Delete Operation for Two Strings

LeetCode Delete Operation for Two Strings Given two words word1 and word2, find the minimum number of steps required to make word1 and word2 the same, where in each step you can delete one character in either string. Example 1:

Input: "sea", "eat"
Output: 2
Explanation: You need one step to make "sea" to "ea" and another step to make "eat" to "ea".
Note:
  1. The length of given words won’t exceed 500.
  2. Characters in given words can only be lower-case letters.

给定两个字符串,求最少的删除次数,使得两个字符串相等。 这其实就是求两个字符串的最长公共子序列,因为最少的删除次数之后,两个字符串都变成了lcs,则每个字符串删除的次数就是原始长度减去lcs的长度。 代码如下: [cpp] class Solution { private: int lcs(const string& s1, const string& s2) { int n1 = s1.size(), n2 = s2.size(); vector<int> dp1(n2 + 1, 0), dp2(n2 + 1, 0); int ans = 0; for (int i = 1; i <= n1; ++i) { for (int j = 1; j <= n2; ++j) { if (s1[i – 1] == s2[j – 1])dp2[j] = dp1[j – 1] + 1; else dp2[j] = max(dp1[j], dp2[j – 1]); ans = max(ans, dp2[j]); } dp1.swap(dp2); } return ans; } public: int minDistance(string word1, string word2) { int l = lcs(word1, word2); return word1.size() – l + word2.size() – l; } }; [/cpp] 本代码提交AC,用时52MS。]]>

LeetCode Combination Sum III

216. Combination Sum III

Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers. Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers. Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers. Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers.

Note:

  • All numbers will be positive integers.
  • The solution set must not contain duplicate combinations.

Example 1:

Input: k = 3, n = 7
Output: [[1,2,4]]

Example 2:

Input: k = 3, n = 9 Output: [[1,2,6], [1,3,5], [2,3,4]]

从1~9中取k个数,使得这k个数的和等于n,求出所有取数方案。 简单的递归题,为了不重复,每次从上次取数的下一个取,代码如下:

class Solution {
private:
    void dfs(vector<vector<int> >& ans, vector<int>& cand, int step, const int& k, int sum)
    {
        if (cand.size() == k && sum == 0) {
            ans.push_back(cand);
            return;
        }
        for (int i = step; i <= 9; ++i) {
            if (i > sum)
                break;
            cand.push_back(i);
            dfs(ans, cand, i + 1, k, sum – i);
            cand.pop_back();
        }
    }
public:
    vector<vector<int> > combinationSum3(int k, int n)
    {
        vector<vector<int> > ans;
        vector<int> cand;
        dfs(ans, cand, 1, k, n);
        return ans;
    }
};

本代码提交AC,用时3MS。

二刷。代码如下:

class Solution {
	void dfs(vector<vector<int>> &ans, vector<int> &cand, int k, int n, int &sum) {
		if (cand.size() == k && sum == n) {
			ans.push_back(cand);
			return;
		}
		if (cand.size() >= k || sum >= n)return;
		int start = 1;
		if (!cand.empty())start = cand.back() + 1;
		for (int i = start; i <= 9; ++i) {
			cand.push_back(i);
			sum += i;
			dfs(ans, cand, k, n, sum);
			sum -= i;
			cand.pop_back();
		}
	}
public:
	vector<vector<int>> combinationSum3(int k, int n) {
		if (k > 9 || n > 45)return { };
		vector<vector<int>> ans;
		vector<int> cand;
		int sum = 0;
		dfs(ans, cand, k, n, sum);
		return ans;
	}
};

本代码提交AC,用时0MS。

LeetCode Kth Smallest Element in a Sorted Matrix

378. Kth Smallest Element in a Sorted Matrix 378. Kth Smallest Element in a Sorted Matrix

Given a n x n matrix where each of the rows and columns are sorted in ascending order, find the kth smallest element in the matrix.

Note that it is the kth smallest element in the sorted order, not the kth distinct element.

Example:

matrix = [
   [ 1,  5,  9],
   [10, 11, 13],
   [12, 13, 15]
],
k = 8,

return 13.

Note:
You may assume k is always valid, 1 ≤ k ≤ n2. 378. Kth Smallest Element in a Sorted Matrix


给定一个矩阵,该矩阵每行和每列都是有序的,要找出第k小的数。 如果只利用每行或者每列是有序的,则可以使用堆解决。我们以行为例,那么每行都是有序的,则相当于把所有行进行n路归并,然后找到第k小的数。所以我们构建一个最小堆,首先把所有行的首元素放到堆中,然后n路归并k次,每次弹出堆顶元素(即当前最小值),然后把原堆顶元素所在行的下一个元素放入堆中。k次归并结束之后,堆顶元素即为第k小的元素。 代码如下:

class Solution {
private:
    struct Node {
        int val, row, col;
        Node(int v = 0, int r = 0, int c = 0)
            : val(v)
            , row(r)
            , col(c){};
        friend bool operator<(const Node& n1, const Node& n2) { return n1.val > n2.val; }
    };
public:
    int kthSmallest(vector<vector<int> >& matrix, int k)
    {
        int n = matrix.size();
        priority_queue<Node> pn;
        for (int i = 0; i < n; ++i)
            pn.push(Node(matrix[i][0], i, 0));
        Node t;
        while (k–) {
            t = pn.top();
            pn.pop();
            if (t.col < n – 1)
                pn.push(Node(matrix[t.row][t.col + 1], t.row, t.col + 1));
        }
        return t.val;
    }
};

本代码提交AC,用时45MS。时间复杂度是O(klgn),堆的大小为n,每次归并调整堆需要lgn时间,一共需要归并k次,所以总的时间复杂度是O(klgn)。
另外用二分的方法可以同时利用行有序和列有序的特点。这种矩阵可以看成一个曲面,曲面的最低点为左上角元素left,最高点为右下角元素right,所以曲面就是从左上角向上延伸到右下角(想象一下MATLAB画的图)。那么第k小的数肯定在[left,right]范围内,我们可以二分查找这个区间。假设中点是mid,则我们在每一行找找比mid小的数有多少个,加起来如果等于cnt,则说明mid这个数排在第cnt位。因为每一行也是有序的,所以可以直接用upper_bound查找第一个比mid大的数。
代码如下:

class Solution {
public:
    int kthSmallest(vector<vector<int> >& matrix, int k)
    {
        int n = matrix.size(), left = matrix[0][0], right = matrix[n – 1][n – 1];
        while (left <= right) {
            int mid = left + (right – left) / 2;
            int cnt = 0;
            for (int i = 0; i < n; ++i) {
                cnt += upper_bound(matrix[i].begin(), matrix[i].end(), mid) – matrix[i].begin();
            }
            if (cnt < k)
                left = mid + 1;
            else
                right = mid – 1;
        }
        return left;
    }
};

本代码提交AC,用时43MS。时间复杂度是O(lgX nlgn),X为[left,right]的区间大小,ngln是对于每个mid,都需要在每一行二分查找比mid小的数的个数。
还可以将上述复杂度降为O(lgX n)。就是在找cnt,不需要每一行都二分查找,我们可以从矩阵的左下角往右上角阶梯查找,如果要查找的数更大,则往右移,否则往上移,每次查询只需要O(n)的时间,所以总时间是O(lgX n)。
代码如下:

class Solution {
private:
    int count_less_equal(vector<vector<int> >& matrix, int num)
    {
        int n = matrix.size(), i = n – 1, j = 0, cnt = 0;
        while (i >= 0 && j < n) {
            if (matrix[i][j] <= num) {
                cnt += i + 1;
                ++j;
            }
            else
                –i;
        }
        return cnt;
    }
public:
    int kthSmallest(vector<vector<int> >& matrix, int k)
    {
        int n = matrix.size(), left = matrix[0][0], right = matrix[n – 1][n – 1];
        while (left <= right) {
            int mid = left + (right – left) / 2;
            int cnt = count_less_equal(matrix, mid);
            if (cnt < k)
                left = mid + 1;
            else
                right = mid – 1;
        }
        return left;
    }
};

本代码提交AC,用时39MS。

LeetCode Kill Process

LeetCode Kill Process Given n processes, each process has a unique PID (process id) and its PPID (parent process id). Each process only has one parent process, but may have one or more children processes. This is just like a tree structure. Only one process has PPID that is 0, which means this process has no parent process. All the PIDs will be distinct positive integers. We use two list of integers to represent a list of processes, where the first list contains PID for each process and the second list contains the corresponding PPID. Now given the two lists, and a PID representing a process you want to kill, return a list of PIDs of processes that will be killed in the end. You should assume that when a process is killed, all its children processes will be killed. No order is required for the final answer. Example 1:

Input:
pid =  [1, 3, 10, 5]
ppid = [3, 0, 5, 3]
kill = 5
Output: [5,10]
Explanation:
           3
         /   \
        1     5
             /
            10
Kill 5 will also kill 10.
Note:
  1. The given kill id is guaranteed to be one of the given PIDs.
  2. n >= 1.

给定一个父子进程的对应关系,现在要kill掉某个进程id,那么id的子进程,孙进程也会被kill掉,问最终被kill掉的进程有哪些。 简单题。先使用map把父子进程的对应关系存起来,因为是一个父亲可能有多个孩子进程,所以要用multimap。然后用bfs类似于树的层次遍历,把所有孩子进程遍历一遍并存到结果数组中。 代码如下,刚好看了C++ primer的unordered_multimap的范围查找,用equal_range很方便。 [cpp] class Solution { public: vector<int> killProcess(vector<int>& pid, vector<int>& ppid, int kill) { unordered_multimap<int, int> umm; for (int i = 0; i < pid.size(); ++i) { umm.insert(pair<int, int>(ppid[i], pid[i])); } vector<int> ans; queue<int> q; q.push(kill); while (!q.empty()) { int id = q.front(); q.pop(); ans.push_back(id); auto r = umm.equal_range(id); for (auto i = r.first; i != r.second; ++i)q.push(i->second); } return ans; } }; [/cpp] 本代码提交AC,用时166MS。]]>

LeetCode Heaters

LeetCode Heaters Winter is coming! Your first job during the contest is to design a standard heater with fixed warm radius to warm all the houses. Now, you are given positions of houses and heaters on a horizontal line, find out minimum radius of heaters so that all houses could be covered by those heaters. So, your input will be the positions of houses and heaters seperately, and your expected output will be the minimum radius standard of heaters. Note:

  1. Numbers of houses and heaters you are given are non-negative and will not exceed 25000.
  2. Positions of houses and heaters you are given are non-negative and will not exceed 10^9.
  3. As long as a house is in the heaters’ warm radius range, it can be warmed.
  4. All the heaters follow your radius standard and the warm radius will the same.
Example 1:
Input: [1,2,3],[2]
Output: 1
Explanation: The only heater was placed in the position 2, and if we use the radius 1 standard, then all the houses can be warmed.
Example 2:
Input: [1,2,3,4],[1,4]
Output: 1
Explanation: The two heater was placed in the position 1 and 4. We need to use radius 1 standard, then all the houses can be warmed.

给定房子和加热器的位置,问加热器的最小半径是所少才能使所有房子都在加热的范围之内。一个加热器的加热范围是一个圆,所有加热器的加热半径都是一样的。 要保证每个房子都在加热范围之内,且加热器的半径最小,则房子i肯定被紧邻i前后的两个加热器之一覆盖,其他加热器距离i的距离肯定比紧邻i前后的两个加热器远。比如x, i, y,i表示房子坐标,x和y分别表示紧邻i的两个加热器坐标,则覆盖i的最小半径应该是min(i-x,y-i)。 所以问题就转换为对每个房子坐标i,去加热器坐标数组中找到紧邻i前后的两个加热器坐标x和y,然后根据上述公式更新结果。为了便于查找,先对加热器坐标排序,然后直接二分查找就好了。 代码如下: [cpp] class Solution { public: int findRadius(vector<int>& houses, vector<int>& heaters) { sort(heaters.begin(), heaters.end()); int ans = 0; for (int i = 0; i < houses.size(); ++i) { int &pos = houses[i]; int r = INT_MAX; auto lb = lower_bound(heaters.begin(), heaters.end(), pos); if (lb > heaters.begin())r = min(r, pos – *(lb – 1)); auto ub = lower_bound(heaters.begin(), heaters.end(), pos); if (ub < heaters.end())r = min(r, *ub – pos); ans = max(ans, r); } return ans; } }; [/cpp] 本代码提交AC,用时89MS。 还可以自己写二分查找代码,如下: [cpp] class Solution { private: int my_lower_bound(vector<int>& v, int target) { int l = 0, r = v.size() – 1; while (l <= r) { int m = l + (r – l) / 2; if (target > v[m])l = m + 1; else r = m – 1; } return l; } public: int findRadius(vector<int>& houses, vector<int>& heaters) { sort(heaters.begin(), heaters.end()); int ans = 0, n = houses.size(), m = heaters.size(); for (int i = 0; i < n; ++i) { int &pos = houses[i]; int r = INT_MAX; int lb = my_lower_bound(heaters, pos); if (lb > 0)r = min(r, pos – heaters[lb – 1]); if (lb < m)r = min(r, heaters[lb] – pos); ans = max(ans, r); } return ans; } }; [/cpp] 本代码提交AC,用时76MS。]]>

LeetCode Permutation in String

LeetCode Permutation in String Given two strings s1 and s2, write a function to return true if s2 contains the permutation of s1. In other words, one of the first string’s permutations is the substring of the second string. Example 1:

Input:s1 = "ab" s2 = "eidbaooo"
Output:True
Explanation: s2 contains one permutation of s1 ("ba").
Example 2:
Input:s1= "ab" s2 = "eidboaoo"
Output: False
Note:
  1. The input strings only contain lower case letters.
  2. The length of both given strings is in range [1, 10,000].

给定两个字符串s1和s2,问s1的排列是否是s2的子串。 暴力方法是枚举s2的每个字符,如果在s1中,则在s2中取等长的子串,hash判断s2的子串和s1是否是同一个串的不同排列。 代码如下: [cpp] class Solution { public: bool checkInclusion(string s1, string s2) { int n = s1.size(), m = s2.size(); if (n > m)return false; unordered_map<char, int> hash1; for (int i = 0; i < n; ++i)++hash1[s1[i]]; for (int i = 0; i < m; ++i) { if (hash1.find(s2[i]) != hash1.end()) { if (i + n <= m) { unordered_map<char, int> hash2; for (int j = i; j < i + n; ++j)++hash2[s2[j]]; if (hash1 == hash2)return true; } } } return false; } }; [/cpp] 本代码提交AC,用时1365MS。 优化方法是使用滑动窗口方法,假设s1的长度为n。先hash s1,再在s2中开长度为n的窗口,判断窗口内的子串hash是否和s1的hash相等,相等则返回tru,否则窗口向右滑动一格,即增加右边一个字符频率,同时减掉左边一个字符频率,如此循环。 代码如下: [cpp] class Solution { public: bool checkInclusion(string s1, string s2) { int n = s1.size(), m = s2.size(); if (n > m)return false; vector<int> hash1(26, 0), hash2(26, 0); for (int i = 0; i < n; ++i) { ++hash1[s1[i] – ‘a’]; ++hash2[s2[i] – ‘a’]; } if (hash1 == hash2)return true; for (int i = n; i < m; ++i) { ++hash2[s2[i] – ‘a’]; –hash2[s2[i – n] – ‘a’]; if (hash1 == hash2)return true; } return false; } }; [/cpp] 本代码提交AC,用时13MS。]]>

LeetCode Brick Wall

LeetCode Brick Wall There is a brick wall in front of you. The wall is rectangular and has several rows of bricks. The bricks have the same height but different width. You want to draw a vertical line from the top to the bottom and cross the least bricks. The brick wall is represented by a list of rows. Each row is a list of integers representing the width of each brick in this row from left to right. If your line go through the edge of a brick, then the brick is not considered as crossed. You need to find out how to draw the line to cross the least bricks and return the number of crossed bricks. You cannot draw a line just along one of the two vertical edges of the wall, in which case the line will obviously cross no bricks. Example:

Input:
[[1,2,2,1],
 [3,1,2],
 [1,3,2],
 [2,4],
 [3,1,2],
 [1,3,1,1]]
Output: 2
Explanation:

Note:
  1. The width sum of bricks in different rows are the same and won’t exceed INT_MAX.
  2. The number of bricks in each row is in range [1,10,000]. The height of wall is in range [1,10,000]. Total number of bricks of the wall won’t exceed 20,000.

hihoCoder 1494-一面砖墙完全一样的题,不解释。 代码如下: [cpp] class Solution { public: int leastBricks(vector<vector<int>>& wall) { int height = wall.size(); unordered_map<int, int> cnt; int maxedges = 0; for (int i = 0; i < height; ++i) { int len = 0; for (int j = 0; j < wall[i].size() – 1; ++j) { len += wall[i][j]; ++cnt[len]; maxedges = max(maxedges, cnt[len]); } } return height – maxedges; } }; [/cpp] 本代码提交AC,用时46MS。]]>

LeetCode Subarray Sum Equals K

560. Subarray Sum Equals K

Given an array of integers and an integer k, you need to find the total number of continuous subarrays whose sum equals to k.

Example 1:

Input:nums = [1,1,1], k = 2
Output: 2

Note:

  1. The length of the array is in range [1, 20,000].
  2. The range of numbers in the array is [-1000, 1000] and the range of the integer k is [-1e7, 1e7].

给定一个数组,问有多少个子数组的和等于k。
暴力方法$O(n^3)$肯定不行,这种连续子数组的问题,肯定会用到数组的前缀和,所以先把前缀和求出来sum[i],这样任意区间[i,j]之间的和都可以用sum[i]-sum[i-1]求到。不过还是需要$O(n^2)$的时间,代码如下:

class Solution {
public:
    int subarraySum(vector<int>& nums, int k)
    {
        int n = nums.size();
        if (n == 0)
            return 0;
        vector<int> sum(n + 1, 0);
        for (int i = 1; i <= n; ++i)
            sum[i] = sum[i – 1] + nums[i – 1];
        int ans = 0;
        for (int i = 0; i < n; ++i) {
            for (int j = i + 1; j <= n; ++j) {
                if (sum[j] – sum[i] == k)
                    ++ans;
            }
        }
        return ans;
    }
};

本代码提交AC,用时533MS。

看了下tag要用map来做。我们把所有前缀和及其频率存到一个map中,假设当前前缀和为sum,则如果sum-k也在map中,说明由产生sum-k前缀和的位置到当前位置的和是k。
比如样例[1,1,1],遇到第一个1时,前缀和为1,之前没有前缀和为1的情况,所以map[1]=1。当加到最后一个数时,前缀和sum=3,sum-k=1也在map中,正好说明从1开始到结束的位置的和为2,如果map[1]=2,说明有两个前缀和等于1的位置,也就有两个连续和为2的子数组。
代码如下,注意只能在遍历的同时求ans,不能等map都构建好了再求ans,这样保证前缀和为sum-k的位置肯定在i前面,也就是我们统一前缀和为k的结束位置为i,做到不重不漏。

class Solution {
public:
    int subarraySum(vector<int>& nums, int k)
    {
        int n = nums.size();
        if (n == 0)
            return 0;
        int ans = 0, sum = 0;
        unordered_map<int, int> cnt;
        for (int i = 0; i < n; ++i) {
            ++cnt[sum];
            sum += nums[i];
            ans += cnt[sum – k];
        }
        return ans;
    }
};

本代码提交AC,用时36MS。

二刷。思路同上,但不把sum=0插入到map中,会不会更好理解一些:

class Solution {
public:
	int subarraySum(vector<int>& nums, int k) {
		int i = 0, j = 0, n = nums.size();
		map<int, int> sum_cnt;
		int sum = 0, ans = 0;
		for (int i = 0; i < n; ++i) {
			sum += nums[i];
			if (sum == k)++ans;
			if (sum_cnt.find(sum - k) != sum_cnt.end()) {
				ans += sum_cnt[sum - k];
			}
			++sum_cnt[sum];
		}
		return ans;
	}
};

本代码提交AC,用时56MS。

LeetCode Subtree of Another Tree

LeetCode Subtree of Another Tree Given two non-empty binary trees s and t, check whether tree t has exactly the same structure and node values with a subtree of s. A subtree of s is a tree consists of a node in s and all of this node’s descendants. The tree s could also be considered as a subtree of itself. Example 1: Given tree s:

     3
    / \
   4   5
  / \
 1   2
Given tree t:
   4
  / \
 1   2
Return true, because t has the same structure and node values with a subtree of s. Example 2: Given tree s:
     3
    / \
   4   5
  / \
 1   2
    /
   0
Given tree t:
   4
  / \
 1   2
Return false.
判断二叉树t是否是二叉树s的子树。如果t是s从node0开始的子树,则t必须和node0子树完全一样,node0不能有多余的孩子,比如样例2中node0的子树多有一个节点0,所以是False。 首先写一个子程序check判断子树s和t是否相等,然后在主程序中使用先序遍历s,如果发现s的某个节点node0的值和t的根节点相等,则可以进入check(node0,t)判断node0子树是否和t相等。 代码如下: [cpp] class Solution { private: bool check(TreeNode* s, TreeNode* t) { if ((s == NULL && t != NULL) || (s != NULL&&t == NULL))return false; if (s == NULL && t == NULL)return true; //s!=NULL&&t!=NULL return (s->val == t->val) && check(s->left, t->left) && check(s->right, t->right); } public: bool isSubtree(TreeNode* s, TreeNode* t) { if (t == NULL)return true; if (s == NULL)return false; queue<TreeNode*> q; q.push(s); while (!q.empty()) { TreeNode *tmp = q.front(); q.pop(); if (tmp->val == t->val) { if (check(tmp, t))return true; } if (tmp->left != NULL)q.push(tmp->left); if (tmp->right != NULL)q.push(tmp->right); } return false; } }; [/cpp] 本代码提交AC,用时29MS。 还有一种更简洁漂亮的解法。如果t是s的子树,有三种情况,t要么和s完全相等check(s,t),要么等于s的某个左子树isSubtree(s->left,t),要么等于s的某个右子树isSubtree(s->right,t)。所以主程序和子程序都可以递归。 代码如下: [cpp] class Solution { private: bool check(TreeNode* s, TreeNode* t) { if ((s == NULL && t != NULL) || (s != NULL&&t == NULL))return false; if (s == NULL && t == NULL)return true; //s!=NULL&&t!=NULL return (s->val == t->val) && check(s->left, t->left) && check(s->right, t->right); } public: bool isSubtree(TreeNode* s, TreeNode* t) { if (t == NULL)return true; if (s == NULL)return false; if (check(s, t))return true; return isSubtree(s->left, t) || isSubtree(s->right, t); } }; [/cpp] 本代码提交AC,用时32MS。]]>