Monthly Archives: March 2017

LeetCode Path Sum III

LeetCode Path Sum III You are given a binary tree in which each node contains an integer value. Find the number of paths that sum to a given value. The path does not need to start or end at the root or a leaf, but it must go downwards (traveling only from parent nodes to child nodes). The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000. Example:

root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8
      10
     /  \
    5   -3
   / \    \
  3   2   11
 / \   \
3  -2   1
Return 3. The paths that sum to 8 are:
1.  5 -> 3
2.  5 -> 2 -> 1
3. -3 -> 11

问二叉树中有多少条路径和等于sum的路径,这里的路径不一定要起于根节点,也不一定要终于叶子结点,但是必须从从上往下(从父亲到孩子)。 我一开始的解法是,对每个节点,保留从其所有父亲节点到该节点的路径和,每个节点都统计到当前节点的路径和等于sum的路径数。 代码如下: [cpp] class Solution { private: void dfs(TreeNode* root, vector<int> all, int target, int& ans) { vector<int> newAll = { root->val }; for (int i = 0; i < all.size(); ++i)newAll.push_back(root->val + all[i]); for (int i = 0; i < newAll.size(); ++i) { if (newAll[i] == target)++ans; } if (root->left)dfs(root->left, newAll, target, ans); if (root->right)dfs(root->right, newAll, target, ans); } public: int pathSum(TreeNode* root, int sum) { if (root == NULL)return 0; int ans = 0; dfs(root, {}, sum, ans); return ans; } }; [/cpp] 本代码提交AC,用时62MS。这种解法需要保存所有的路径和,且有vector的复制,效率较低。 我这种解法是以每个节点作为终点统计一下路径和,网上有另一种解法,以每个节点作为开始节点,统计以这个点开始的所有路径和是否等于sum,然后递归的在其子树进行统计。 对于每个节点,走到其孩子节点时,对应的sum需要更新。代码如下: [cpp] class Solution { private: int dfs(TreeNode* root, int sum) { if (root == NULL)return 0; int ans = 0; if (root->val == sum)++ans; ans += dfs(root->left, sum – root->val); ans += dfs(root->right, sum – root->val); return ans; } public: int pathSum(TreeNode* root, int sum) { if (root == NULL)return 0; return dfs(root, sum) + pathSum(root->left, sum) + pathSum(root->right, sum); } }; [/cpp] 本代码提交AC,用时32MS,效率更高。]]>

LeetCode Delete Node in a BST

LeetCode Delete Node in a BST Given a root node reference of a BST and a key, delete the node with the given key in the BST. Return the root node reference (possibly updated) of the BST. Basically, the deletion can be divided into two stages:

  1. Search for a node to remove.
  2. If the node is found, delete the node.
Note: Time complexity should be O(height of tree). Example:
root = [5,3,6,2,4,null,7]
key = 3
    5
   / \
  3   6
 / \   \
2   4   7
Given key to delete is 3. So we find the node with value 3 and delete it.
One valid answer is [5,4,6,2,null,null,7], shown in the following BST.
    5
   / \
  4   6
 /     \
2       7
Another valid answer is [5,2,6,null,4,null,7].
    5
   / \
  2   6
   \   \
    4   7

从二叉搜索树中删除一个节点,并返回一个新的二叉搜索树;如果该节点不存在,则返回原二叉搜索树。 因为是BST,所以很容易找到等于value的节点,问题的关键是怎样删除这个节点,并且保持二叉搜索树的特性:左孩子<根节点<右孩子。 如果要删除的节点的左子树为空,则删除该节点,返回该节点的右子树即可;类似的,如果要删除的节点的右子树为空,则删除该节点,返回该节点的左子树。 难点就是当该节点的左子树和右子树都不为空时,该怎么处理。如下图,假设我们找到了root的值等于key,则需要删除root节点,并调整其子树使满足BST的性质。
       root
      /    \
   left  right
  /   \  /   \
 x    l r     y
具体有两种方案,题目中也举了例子,即可以把left放到root的位置,或者把right放到root的位置。 现在假设要把left放到root的位置,则需要处理left的右子树l。l肯定要被切下来,又l比left大,所以l应该接在right子树,具体位置是接在right子树的最小节点上,即right的最左下端的叶子节点r。也就是变成下面这样:
    left            right
    /  \            /   \
   x               r     y
                  /
                 l 
最后把right子树接在left右子树即可:
            left
            /  \
           x    right
                /   \
               r     y
              /
             l  
知道了调整的思路,代码就好写了: [cpp] class Solution { private: TreeNode* justify(TreeNode *root) { if (root->left == NULL || root->right == NULL)return root->left == NULL ? root->right : root->left; TreeNode *left = root->left, *right = root->right; TreeNode *l = left->right, *r = right; while (r->left) r = r->left; r->left = l; left->right = right; return left; } public: TreeNode* deleteNode(TreeNode* root, int key) { TreeNode *dummy = new TreeNode(-1), *pre = dummy, *child = root; dummy->right = root; while (child != NULL && child->val != key) { pre = child; if (key < child->val) child = child->left; else child = child->right; } if (child == NULL)return dummy->right; if (pre->left == child)pre->left = justify(child); else pre->right = justify(child); return dummy->right; } }; [/cpp] 本代码提交AC,用时33MS。 如果要把right放到root的位置,思路是类似的,需要把right的左子树切下来接到left最右下端的叶子节点上。 参考:https://segmentfault.com/a/1190000005032508]]>

LeetCode Set Matrix Zeroes

73. Set Matrix Zeroes

Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in-place.

Example 1:

Input: 
[
  [1,1,1],
  [1,0,1],
  [1,1,1]
]
Output: 
[
  [1,0,1],
  [0,0,0],
  [1,0,1]
]

Example 2:

Input: 
[
  [0,1,2,0],
  [3,4,5,2],
  [1,3,1,5]
]
Output: 
[
  [0,0,0,0],
  [0,4,5,0],
  [0,3,1,0]
]

Follow up:

  • A straight forward solution using O(mn) space is probably a bad idea.
  • A simple improvement uses O(m + n) space, but still not the best solution.
  • Could you devise a constant space solution?

给定一个矩阵,如果元素(i,j)是0,则把第i行和第j列都赋值为0。要求用常数空间。 因为前面的元素如果赋值为0,会影响后面的行列,所以是否赋值为0需要预先存起来,最后再一次性处理矩阵。 可以用一个行向量row[]和一个列向量col[]分别存储第i行和第j列是否应该赋值为0,具体方法就是扫描矩阵,如果matrix[i][j]==0,则赋值row[i]=0和col[j]=0表明第i行和第j列应该被赋值为0。但是这种方法需要O(m+n)的空间。

为了不使用额外的空间,我们可以借用原矩阵的第一行和第一列当作上面的row[]和col[],但是需要提前判断第一行和第一列是否应该被置为0。具体代码如下:

class Solution {
public:
    void setZeroes(vector<vector<int> >& matrix)
    {
        int m = matrix.size();
        if (m == 0)
            return;
        int n = matrix[0].size();
        if (n == 0)
            return;
        bool clearFirstRow = false, clearFirstColumn = false;
        for (int i = 0; i < m; ++i) { // first column
            if (matrix[i][0] == 0) {
                clearFirstColumn = true;
                break;
            }
        }
        for (int j = 0; j < n; ++j) { // first row
            if (matrix[0][j] == 0) {
                clearFirstRow = true;
                break;
            }
        }
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (matrix[i][j] == 0) {
                    matrix[i][0] = 0;
                    matrix[0][j] = 0;
                }
            }
        }
        for (int i = 1; i < m; ++i) {
            for (int j = 1; j < n; ++j) {
                if (matrix[0][j] == 0 || matrix[i][0] == 0)
                    matrix[i][j] = 0;
            }
        }
        if (clearFirstRow) {
            for (int j = 0; j < n; ++j)
                matrix[0][j] = 0;
        }
        if (clearFirstColumn) {
            for (int i = 0; i < m; ++i)
                matrix[i][0] = 0;
        }
    }
};

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

LeetCode Implement Stack using Queues

225. Implement Stack using Queues

Implement the following operations of a stack using queues.

  • push(x) — Push element x onto stack.
  • pop() — Removes the element on top of the stack.
  • top() — Get the top element.
  • empty() — Return whether the stack is empty.

Example:

MyStack stack = new MyStack();

stack.push(1);
stack.push(2);  
stack.top();   // returns 2
stack.pop();   // returns 2
stack.empty(); // returns false

Notes:

  • You must use only standard operations of a queue — which means only push to backpeek/pop from frontsize, and is empty operations are valid.
  • Depending on your language, queue may not be supported natively. You may simulate a queue by using a list or deque (double-ended queue), as long as you use only standard operations of a queue.
  • You may assume that all operations are valid (for example, no pop or top operations will be called on an empty stack). 225. Implement Stack using Queues

LeetCode Implement Queue using Stacks正好相反,本题要用队列实现堆栈的效果。 队列是先进先出的,而堆栈是后进先出。如果用队列q保存数据,则要实现堆栈的pop效果时,需要获取到q的队尾元素,可以不断把q的数据从队首弹出,同时压回队尾,重复n-1次,此时队首元素就是原来的队尾元素了。堆栈的top效果和push的实现方法是类似的。 这种题目就是数据不断的倒腾。。。 完整代码如下:

class MyStack {
private:
    queue<int> m_q;
public: /** Initialize your data structure here. */
    MyStack() {} /** Push element x onto stack. */
    void push(int x) { m_q.push(x); } /** Removes the element on top of the stack and returns that element. */
    int pop()
    {
        int sz = m_q.size();
        for (int i = 0; i < sz – 1; ++i) {
            m_q.push(m_q.front());
            m_q.pop();
        }
        int front = m_q.front();
        m_q.pop();
        return front;
    } /** Get the top element. */
    int top()
    {
        int sz = m_q.size(), front = m_q.front();
        for (int i = 0; i < sz; ++i) {
            front = m_q.front();
            m_q.push(front);
            m_q.pop();
        }
        return front;
    } /** Returns whether the stack is empty. */
    bool empty() { return m_q.empty(); }
};

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

二刷。用两个queue来模拟stack,不如上面的解法好看:

class MyStack {
private:
	vector<queue<int>> vq_;
	int data_queue_id_;
public:
	/** Initialize your data structure here. */
	MyStack() {
		vq_.push_back(queue<int>());
		vq_.push_back(queue<int>());
		data_queue_id_ = 0;
	}

	/** Push element x onto stack. */
	void push(int x) {
		vq_[data_queue_id_].push(x);
	}

	/** Removes the element on top of the stack and returns that element. */
	int pop() {
		int another_id = 1 - data_queue_id_;
		int last_data = 0;
		while (!vq_[data_queue_id_].empty()) {
			last_data = vq_[data_queue_id_].front();
			vq_[data_queue_id_].pop();
			if (!vq_[data_queue_id_].empty()) {
				vq_[another_id].push(last_data);
			}
		}
		swap(another_id, data_queue_id_);
		return last_data;
	}

	/** Get the top element. */
	int top() {
		int another_id = 1 - data_queue_id_;
		int last_data = 0;
		while (!vq_[data_queue_id_].empty()) {
			last_data = vq_[data_queue_id_].front();
			vq_[data_queue_id_].pop();
			vq_[another_id].push(last_data);
		}
		swap(another_id, data_queue_id_);
		return last_data;
	}

	/** Returns whether the stack is empty. */
	bool empty() {
		return vq_[data_queue_id_].empty();
	}
};

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

LeetCode Integer Break

343. Integer Break

Given a positive integer n, break it into the sum of at least two positive integers and maximize the product of those integers. Return the maximum product you can get.

Example 1:

Input: 2
Output: 1
Explanation: 2 = 1 + 1, 1 × 1 = 1.

Example 2:

Input: 10
Output: 36
Explanation: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36.

Note: You may assume that n is not less than 2 and not larger than 58.


给定一个数n,要求把其拆分成至少两个数的和,使得他们的乘积最大。 数学题,没啥思路,参考网上题解。 把0~10的结果先列出来找找规律:

  • 0:0
  • 1:0
  • 2:1=1*1
  • 3:2=2*1
  • 4:4=2*2
  • 5:6=3*2
  • 6:9=3*3
  • 7:12=3*4
  • 8:18=3*3*2
  • 9:27=3*3*3
  • 10:36=3*3*4

可以发现,n从5开始,都至少分解出来一个3,可以推断的是,当n=11时,在10的基础上,把最后一个4改成5,然后5又可以分解成3*2,所以11=3+3+3+2使得乘积最大。 4只能分解出2+2,1+3的乘积是3小于2*2;5可以分解出3+2,所以也有3。也就是说,当n大于4时,不断分解出3来,直到剩余的数小于4为止。所以有如下代码:

class Solution {
public:
    int integerBreak(int n)
    {
        if (n <= 3)
            return n – 1;
        int ans = 1;
        while (n > 4) {
            ans *= 3;
            n -= 3;
        }
        return ans * n;
    }
};

本代码提交AC,用时0MS。
再次观察上述规律,n=10的结果是n=7=10-3的结果乘以3;n=9的结果也是n=6=9-3的结果乘以3。可以推断,n的结果是(n-3)的结果乘以3。所以先列出前几个结果,后面的结果通过其前3的结果乘以3推导得到。代码如下:

class Solution {
public:
    int integerBreak(int n)
    {
        vector<int> dp = { 0, 0, 1, 2, 4, 6, 9 };
        for (int i = 7; i <= n; ++i)
            dp.push_back(dp[i – 3] * 3);
        return dp[n];
    }
};

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

LeetCode Implement Queue using Stacks

232. Implement Queue using Stacks 232. Implement Queue using Stacks

Implement the following operations of a queue using stacks.

  • push(x) — Push element x to the back of queue.
  • pop() — Removes the element from in front of queue.
  • peek() — Get the front element.
  • empty() — Return whether the queue is empty.

Example:

MyQueue queue = new MyQueue();

queue.push(1);
queue.push(2);  
queue.peek();  // returns 1
queue.pop();   // returns 1
queue.empty(); // returns false

Notes:

  • You must use only standard operations of a stack — which means only push to toppeek/pop from topsize, and is empty operations are valid.
  • Depending on your language, stack may not be supported natively. You may simulate a stack by using a list or deque (double-ended queue), as long as you use only standard operations of a stack.
  • You may assume that all operations are valid (for example, no pop or peek operations will be called on an empty queue). 232. Implement Queue using Stacks

本题要求用堆栈来实现队列的功能。因为堆栈是后进先出,而队列是先进先出,顺序正好相反。比如进入队列的顺序是1,2,3,但是进到堆栈stk1之后,从栈顶到栈底的顺序就变成了3,2,1,此时如果要实现队列出队的效果,就必须借助另一个堆栈stk2,把stk1的内容压入到stk2,这样从栈顶到栈底的顺序就和队列一样了,是1,2,3。 所以本题借助两个堆栈stk1和stk2,stk1就是常规的数据来了就压栈,当需要实现队列的pop效果时,就借助stk2倒腾一下,如果又要实现队列的push效果时,又要把stk2的数据捣腾回stk1。 总的来说,我们使用懒人规则,每次直到调用某个操作,且当前stk*不能满足要求时,才捣腾stk1和stk2。 完整代码如下:

class MyQueue {
private:
    stack<int> stk1, stk2; // 输入来源1,2,3,stk1从栈底到栈顶的顺序是1,2,3,stk2从栈底到栈顶的顺序是3,2,1
public: /** Initialize your data structure here. */
    MyQueue() {} /** Push element x to the back of queue. */
    void push(int x)
    {
        while (!stk2.empty()) {
            stk1.push(stk2.top());
            stk2.pop();
        }
        stk1.push(x);
    } /** Removes the element from in front of queue and returns that element. */
    int pop()
    {
        while (!stk1.empty()) {
            stk2.push(stk1.top());
            stk1.pop();
        }
        int top = stk2.top();
        stk2.pop();
        return top;
    } /** Get the front element. */
    int peek()
    {
        while (!stk1.empty()) {
            stk2.push(stk1.top());
            stk1.pop();
        }
        return stk2.top();
    } /** Returns whether the queue is empty. */
    bool empty() { return stk1.empty() && stk2.empty(); }
};

本代码提交AC,用时3MS。
二刷。其实push的时候可以不需要把stk2的数据倒腾回stk1,stk2的数据始终是队列头的,stk1的数据始终是队列尾的,代码如下:

class MyQueue {
private:
    stack<int> stk1, stk2;
    void adjust()
    {
        while (!stk1.empty()) {
            stk2.push(stk1.top());
            stk1.pop();
        }
    }
public: /** Initialize your data structure here. */
    MyQueue() {} /** Push element x to the back of queue. */
    void push(int x) { stk1.push(x); } /** Removes the element from in front of queue and returns that element. */
    int pop()
    {
        if (stk2.empty())
            adjust();
        int ans = stk2.top();
        stk2.pop();
        return ans;
    } /** Get the front element. */
    int peek()
    {
        if (stk2.empty())
            adjust();
        int ans = stk2.top();
        return ans;
    } /** Returns whether the queue is empty. */
    bool empty() { return stk1.empty() && stk2.empty(); }
};

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

LeetCode Longest Substring with At Least K Repeating Characters

LeetCode Longest Substring with At Least K Repeating Characters Find the length of the longest substring T of a given string (consists of lowercase letters only) such that every character in T appears no less than k times. Example 1:

Input:
s = "aaabb", k = 3
Output:
3
The longest substring is "aaa", as 'a' is repeated 3 times.
Example 2:
Input:
s = "ababbc", k = 2
Output:
5
The longest substring is "ababb", as 'a' is repeated 2 times and 'b' is repeated 3 times.

给定一个字符串s和数字k,求s的子串中每个字母都至少出现k次的最长子串的长度。 因为题目规定字符串中只有26个小写字母,所以可以用一个int来Hash某个子串,如果某字母出现次数小于k次,则对应位为1,否则对应位为0。最后,在遍历的过程中,判断子串的Hash值是否等于0,如果是则该子串满足要求,更新最大长度。 完整代码如下: [cpp] class Solution { public: int longestSubstring(string s, int k) { int maxLen = 0; for (int i = 0; i < s.size(); ++i) { vector<int> mask(26, 0); int j = i, flag = 0; while (j < s.size()) { ++mask[s[j] – ‘a’]; if (mask[s[j] – ‘a’] < k)flag |= (1 << (s[j] – ‘a’)); else flag &= (~(1 << (s[j] – ‘a’))); if (flag == 0)maxLen = max(maxLen, j – i + 1); ++j; } } return maxLen; } }; [/cpp] 本代码提交AC,用时196MS。]]>

LeetCode Perfect Squares

279. Perfect Squares

Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, ...) which sum to n.

Example 1:

Input: n = 12
Output: 3 
Explanation: 12 = 4 + 4 + 4.

Example 2:

Input: n = 13 Output: 2 Explanation: 13 = 4 + 9. 279. Perfect Squares 

本题问一个数n最少能由多少个完全平方数加和得到。 使用动态规划,设dp[i]表示数i最少能由多少个完全平方数加和得到,那么由i再加一个平方数j得到的数i+j*j可以由dp[i]+1个平方数组成。即递推公式为:
$$dp[i+j*j]=min(dp[i]+1)$$
具体实现时,我们是先求dp数组中前面的值dp[i],然后不断缩小并更新dp[i+j*j]的结果。代码如下:

class Solution {
public:
    int numSquares(int n)
    {
        vector<int> dp(n + 1, INT_MAX);
        dp[0] = 0;
        for (int i = 0; i <= n; ++i) {
            for (int j = 1; i + j * j <= n; ++j) {
                dp[i + j * j] = min(dp[i + j * j], dp[i] + 1);
            }
        }
        return dp[n];
    }
};

本代码提交AC,用时99MS。
这题还可以用纯数学的方法来解,涉及到四平方和定理,数学方法暂时就不研究了。

二刷,对于数i,其最大的平方数就是(sqrt(i))^2,所以从sqrt(i)到1都试一试,从哪个降下去的数目最少。对于第一个样例,sqrt(12)=3,所以依次尝试3,2,1,发现2降下去的数目最少,因为3降下去就是9+1+1+1,要4个数,比2降下去4+4+4多。

class Solution {
public:
	int numSquares(int n) {
		vector<int> dp(n + 1, n);
		dp[0] = 0;
		dp[1] = 1;
		for (int i = 2; i <= n; ++i) {
			int max_sqrt = sqrt(i);
			for (int j = max_sqrt; j >= 1; --j) {
				dp[i] = min(dp[i], dp[i - j * j] + 1);
			}
		}
		return dp[n];
	}
};

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

三刷。转换为背包问题,先把所有可能的平方数求出来放到数组squares中,把每个平方数当做一件商品,限制背包容量为n,问最少拿多少件商品能填满背包。则对于每件商品,选择拿或者不拿。完整代码如下:

class Solution {
public:
    int numSquares(int n) {
        vector<int> squares = {0};
        for(int i = 1; i * i <= n; ++i) {
            squares.push_back(i * i);
        }
        int m = squares.size();
        vector<vector<int>> dp(m, vector<int>(n + 1, 0));
        for(int i = 1; i < m; ++i) {
            for(int j = 1; j <= n; ++j) {
                if(i == 1) dp[i][j] = j;
                else {
                    dp[i][j] = dp[i - 1][j];
                    if(j >= squares[i]) dp[i][j] = min(dp[i][j], dp[i][j - squares[i]] + 1);
                }
            }
        }
        return dp[m - 1][n];
    }
};

本代码提交AC,用时688MS。还可以进一步优化,dp数组可以变成一维的。

LeetCode Maximum Product of Word Lengths

LeetCode Maximum Product of Word Lengths Given a string array words, find the maximum value of length(word[i]) * length(word[j]) where the two words do not share common letters. You may assume that each word will contain only lower case letters. If no such two words exist, return 0. Example 1: Given ["abcw", "baz", "foo", "bar", "xtfn", "abcdef"] Return 16 The two words can be "abcw", "xtfn". Example 2: Given ["a", "ab", "abc", "d", "cd", "bcd", "abcd"] Return 4 The two words can be "ab", "cd". Example 3: Given ["a", "aa", "aaa", "aaaa"] Return 0 No such pair of words.


给定一个字符串数组,问两个没有共同字母的字符串的长度之积最大是多少,如果不存在这样两个字符串,则返回0。 常规思路是两层循环,判断两个字符串是否有共同字符,没有就把它俩的长度乘起来,更新最大值。 问题的关键就是如果快速的判断两个字符串是否有共同字符,常规思路是把一个字符串Hash,然后对另一个字符串的每个字符,看是否在前一个字符串中出现。快速方法是,因为题目说明字符串中只有小写字母,也就是只有26种情况,所以我们可以对这26个字母编码成一个26长的bit位,用一个int存储足够。这样判断两个字符串是否有共同字符,只需要把两个int相与,等于0表示没有共同字符。 完整代码如下: [cpp] class Solution { public: int maxProduct(vector<string>& words) { int ans = 0; vector<int> mask(words.size(), 0); for (int i = 0; i < words.size(); ++i) { for (int j = 0; j < words[i].size(); ++j) { mask[i] |= 1 << (words[i][j] – ‘a’); } for (int k = 0; k < i; ++k) { if ((mask[i] & mask[k]) == 0) // 注意 == 的优先级高于 & ans = max(ans, int(words[i].size()*words[k].size())); } } return ans; } }; [/cpp] 本代码提交AC,用时69MS。]]>

LeetCode Range Sum Query – Immutable

LeetCode Range Sum Query – Immutable Given an integer array nums, find the sum of the elements between indices i and j (ij), inclusive. Example:

Given nums = [-2, 0, 3, -5, 2, -1]
sumRange(0, 2) -> 1
sumRange(2, 5) -> -1
sumRange(0, 5) -> -3
Note:
  1. You may assume that the array does not change.
  2. There are many calls to sumRange function.

给定一个固定的数组,要查询某个区间[i,j]之间的和,且这样的查询很多。 明显需要先把结果存起来,这样每次查询的时候直接返回就好。用数组dp[i]表示区间[0,i]之间的和,这样区间[i,j]的和=dp[j]-dp[i-1]。注意当i=0的情况。完整代码如下: [cpp] class NumArray { private: vector<int> dp; public: NumArray(vector<int> nums) { int n = nums.size(); if (n == 0)return; dp.resize(n); dp[0] = nums[0]; for (int i = 1; i < n; ++i)dp[i] = dp[i – 1] + nums[i]; } int sumRange(int i, int j) { if (dp.empty())return 0; return dp[j] – (i == 0 ? 0 : dp[i – 1]); } }; [/cpp] 本代码提交AC,用时206MS。]]>