Showing posts with label 数组. Show all posts
Showing posts with label 数组. Show all posts

Monday, August 7, 2017

[Leetcode] Flatten 2D Vector, Solution

Implement an iterator to flatten a 2d vector.
For example,
Given 2d vector =
[
  [1,2],
  [3],
  [4,5,6]
]
By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,2,3,4,5,6].
Follow up:
As an added challenge, try to code it using only iterators in C++ or iterators in Java.

[Thoughts]
实现题,按层从左到右遍历。

[Code]
1:  class Vector2D {  
2:  public:  
3:    vector<vector<int>> data;  
4:    int x = 0;  
5:    int y = 0;  
6:    int total = 0;  
7:    int visited = 0;  
8:    Vector2D(vector<vector<int>>& vec2d) {  
9:      data = vec2d;  
10:      for(auto list : vec2d) {  
11:        total += list.size();  
12:      }  
13:    }  
14:    
15:    int next() {  
16:      while(data[x].size() == 0) {x++;}  
17:        
18:      int cur = data[x][y];  
19:      if(y+1 == data[x].size()) {  
20:        x = x+1;  
21:        y = 0;  
22:      } else {  
23:        y++;  
24:      }  
25:      visited ++;  
26:      return cur;  
27:    }  
28:    
29:    bool hasNext() {  
30:      if(visited < total) return true;  
31:        
32:      return false;  
33:    }  
34:  };  
35:    
36:  /**  
37:   * Your Vector2D object will be instantiated and called as such:  
38:   * Vector2D i(vec2d);  
39:   * while (i.hasNext()) cout << i.next();  
40:   */  






[Leetcode] Summary Ranges, Solution

Given a sorted integer array without duplicates, return the summary of its ranges.
For example, given [0,1,2,4,5,7], return ["0->2","4->5","7"].

[Thoughts]
一道实现题,本身并没有难度,处理好相关的merge即可。

[Code]
1:    vector<string> summaryRanges(vector<int>& nums) {  
2:      vector<string> result;  
3:      if(nums.size() <1) return result;  
4:        
5:      int start = 0, i =1;  
6:      for(; i< nums.size(); i++){  
7:        if(nums[i] - nums[i-1]==1) continue;  
8:          
9:        if(i-1 == start) {  
10:          result.push_back(to_string(nums[start]));  
11:        } else  
12:          result.push_back(to_string(nums[start]) + "->" + to_string(nums[i-1]));  
13:        start = i;  
14:      }  
15:        
16:      if(i-1 == start) {  
17:        result.push_back(to_string(nums[start]));  
18:      } else  
19:        result.push_back(to_string(nums[start]) + "->" + to_string(nums[i-1]));  
20:      return result;  
21:    }  


[Leetcode] Search a 2D Matrix II, Solution

Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:
  • Integers in each row are sorted in ascending from left to right.
  • Integers in each column are sorted in ascending from top to bottom.
For example,
Consider the following matrix:
[
  [1,   4,  7, 11, 15],
  [2,   5,  8, 12, 19],
  [3,   6,  9, 16, 22],
  [10, 13, 14, 17, 24],
  [18, 21, 23, 26, 30]
]
Given target = 5, return true.
Given target = 20, return false.

[Thoughts]
双指针搜索。只不过因为数组的特殊排序,要从最右上角开始搜索,比如上例中的15.


[Code]
1:    bool searchMatrix(vector<vector<int>>& matrix, int target) {  
2:      int rows = matrix.size();  
3:      if(rows == 0) return false;  
4:      int cols = matrix[0].size();  
5:        
6:      int i = 0, j = cols-1;  
7:      while(j>=0 && i< rows) {  
8:        if(matrix[i][j] == target) return true;  
9:          
10:        if(matrix[i][j] < target) i++;  
11:        else j--;  
12:      }  
13:      return false;  
14:    }  


[Leetcode] Find All Numbers Disappeared in an Array, Solution

Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.
Find all the elements of [1, n] inclusive that do not appear in this array.
Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space.
Example:
Input:
[4,3,2,7,8,2,3,1]

Output:
[5,6]
[Thoughts]
题目里面其实提示复用已有的returned list,所以对数字做一遍统计,把缺失的数字放到returned list的尾部,在返回结果前,把原数组中的数字清除掉即可。


[Code]
1:    vector<int> findDisappearedNumbers(vector<int>& nums) {  
2:      vector<int> result(nums.size(), 0);  
3:        
4:      for(int i =0; i< nums.size(); i++) {  
5:        result[nums[i]-1] = 1;  
6:      }  
7:        
8:      for(int i =0; i< nums.size(); i++) {  
9:        if(result[i] == 0) {  
10:          result.push_back(i+1);  
11:        }  
12:      }  
13:        
14:      result.erase(result.begin(), result.begin() + nums.size());  
15:      return result;  
16:    }  



[Leetcode] Island Perimeter, Solution

You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 represents water. Grid cells are connected horizontally/vertically (not diagonally). The grid is completely surrounded by water, and there is exactly one island (i.e., one or more connected land cells). The island doesn't have "lakes" (water inside that isn't connected to the water around the island). One cell is a square with side length 1. The grid is rectangular, width and height don't exceed 100. Determine the perimeter of the island.
Example:
[[0,1,0,0],
 [1,1,1,0],
 [0,1,0,0],
 [1,1,0,0]]

Answer: 16
Explanation: The perimeter is the 16 yellow stripes in the image below:

[Thoughts]
遍历二维数组,对于每一个land点,统计边数,最后统计周长即可。

[Code]
1:    int islandPerimeter(vector<vector<int>>& grid) {  
2:        
3:      int rows = grid.size();  
4:      if(rows == 0) return 0;  
5:      int cols = grid[0].size();  
6:        
7:      int periMeters = 0;  
8:      for(int i =0; i< rows; i++) {  
9:        for(int j =0; j< cols; j++) {  
10:          if(grid[i][j] == 1) {  
11:            periMeters += surWaters(grid, i, j);  
12:          }  
13:        }  
14:      }  
15:      return periMeters;  
16:    }  
17:      
18:    int surWaters(vector<vector<int>>& grid, int x, int y) {  
19:      int periM = 0;  
20:      // x-1, y  
21:      if(x-1< 0) periM++;  
22:      else {  
23:        periM += (1-grid[x-1][y]);  
24:      }  
25:        
26:      //x+1, y  
27:      if(x+1 > grid.size() -1) periM++;  
28:      else periM += (1-grid[x+1][y]);  
29:        
30:      // x, y-1  
31:      if(y-1 < 0) periM++;  
32:      else periM += (1-grid[x][y-1]);  
33:        
34:      // x, y+1  
35:      if(y+1 > grid[0].size() -1) periM++;  
36:      else periM += (1-grid[x][y+1]);  
37:        
38:      return periM;  
39:    }  


Sunday, July 23, 2017

[Leetcode] Diagonal Traverse, Solution

Given a matrix of M x N elements (M rows, N columns), return all elements of the matrix in diagonal order as shown in the below image.
Example:
Input:
[
 [ 1, 2, 3 ],
 [ 4, 5, 6 ],
 [ 7, 8, 9 ]
]
Output:  [1,2,4,7,5,3,6,8,9]
Explanation:

Note:
  1. The total number of elements of the given matrix will not exceed 10,000.


[Thoughts]
以题中示例为例子,看一下坐标的变化,如下图

在上升通道的时候, row = row -1, col = col +1
在下降通道的时候,row = row +1, col = col -1

当坐标变化超出数组范围的时候,要遵循以下原则调整:
1. 如果row < 0, row = 0, 变换通道
2. 如果col < 0, col = 0, 变换通道
3. 如果 col > N, col = N-1, row = row +2;
4. 如果 row > M, row = M-1. col = col +2;



[Code]
1:    vector<int> findDiagonalOrder(vector<vector<int>>& matrix) {  
2:      if(matrix.size() == 0 || matrix[0].size() == 0) return {};  
3:        
4:      vector<int> result;  
5:        
6:      vector<pair<int, int>> move_delta{{-1, 1}, {1, -1}};  
7:        
8:      int rows = matrix.size(), cols = matrix[0].size();  
9:      int row = 0, col = 0, m = 0;  
10:      for(int i = 0; i< rows * cols; i++) {  
11:        result.push_back(matrix[row][col]);  
12:        row += move_delta[m].first;  
13:        col += move_delta[m].second;  
14:          
15:        if(row >= rows) {  
16:          row = rows-1;  
17:          col = col +2;  
18:          m = 1-m;  
19:        }  
20:          
21:        if(col >= cols) {  
22:          col = cols -1;  
23:          row = row + 2;  
24:          m = 1-m;  
25:        }  
26:          
27:        if(row < 0) {  
28:          row = 0;  
29:          m = 1-m;  
30:        }  
31:          
32:        if(col < 0) {  
33:          col = 0;  
34:          m = 1-m;  
35:        }  
36:      }  
37:      return result;  
38:    }  


Saturday, July 22, 2017

[Leetcode] Missing Ranges, Solution

Given a sorted integer array where the range of elements are in the inclusive range [lowerupper], return its missing ranges.
For example, given [0, 1, 3, 50, 75]lower = 0 and upper = 99, return ["2", "4->49", "51->74", "76->99"].


[Thoughts]

这题并不难,扫一遍数组,对于任意两个相邻的数字,看看他们是否连续,不连续的话生成一个range。

需要注意两点:
1. 可以把lower和upper两个边界值加入到数组里面去,这样避免不必要的if-else。 因为lower和upper不是数组中的数字,他们可以出现在range里面,所以这里添加的边界应该是lower -1 和upper +1
2. 测试数据中有很多边界检测,可以直接用int64_t来跳过检测,省了繁琐的if-else



[Code]
1:    vector<string> findMissingRanges(vector<int>& ori_nums, int lower, int upper) {  
2:      int64_t right = upper;  
3:         int64_t left = lower;  
4:      if(ori_nums.size() == 0) return {getRange(left-1, right+1)};  
5:      vector<int64_t> nums(ori_nums.size());  
6:      std::copy ( ori_nums.begin(), ori_nums.end(), nums.begin() );  
7:        
8:      // insert lower and upper as boundary of the array  
9:      nums.insert(nums.begin(), left-1);  
10:      nums.push_back(right+1);  
11:        
12:      int64_t pre = nums[0];  
13:      vector<string> result;  
14:      for(int i = 1; i< nums.size(); i++) {  
15:        if(nums[i]- pre > 1) {  
16:          string range = getRange(pre, nums[i]);  
17:          result.push_back(range);  
18:        }  
19:        pre = nums[i];  
20:      }  
21:      return result;  
22:    }  
23:      
24:    string getRange(int64_t start, int64_t end) {  
25:    
26:      if(end - start <= 2) return to_string(start+1);  
27:    
28:      return to_string(start+1) + "->" + to_string(end-1);  
29:    }  

[Leetcode] Ternary Expression Parser, Solution

Given a string representing arbitrarily nested ternary expressions, calculate the result of the expression. You can always assume that the given expression is valid and only consists of digits 0-9?:T and F (T and F represent True and False respectively).
Note:
  1. The length of the given string is ≤ 10000.
  2. Each number will contain only one digit.
  3. The conditional expressions group right-to-left (as usual in most languages).
  4. The condition will always be either T or F. That is, the condition will never be a digit.
  5. The result of the expression will always evaluate to either a digit 0-9T or F.
Example 1:
Input: "T?2:3"

Output: "2"

Explanation: If true, then result is 2; otherwise result is 3.
Example 2:
Input: "F?1:T?4:5"

Output: "4"

Explanation: The conditional expressions group right-to-left. Using parenthesis, it is read/evaluated as:

             "(F ? 1 : (T ? 4 : 5))"                   "(F ? 1 : (T ? 4 : 5))"
          -> "(F ? 1 : 4)"                 or       -> "(T ? 4 : 5)"
          -> "4"                                    -> "4"
Example 3:
Input: "T?T?F:5:3"

Output: "F"

Explanation: The conditional expressions group right-to-left. Using parenthesis, it is read/evaluated as:

             "(T ? (T ? F : 5) : 3)"                   "(T ? (T ? F : 5) : 3)"
          -> "(T ? F : 3)"                 or       -> "(T ? F : 5)"
          -> "F"                                    -> "F"


[Thoughts]

从右往左扫,发现?号就处理掉,最后的结果就是。


[Code]
1:    string parseTernary(string expression) {  
2:      int len = expression.size();  
3:        
4:      if(len == 0) return expression;  
5:        
6:      for(int i = len-1; i>=0; i--) {  
7:        if(expression[i] != '?') continue;  
8:          
9:        int index = i;  
10:        char result;  
11:        if(expression[index-1] == 'T'){  
12:          result = expression[index+1];  
13:        }else {  
14:          result = expression[index+3];  
15:        }  
16:          
17:        expression.erase(index -1, 5);  
18:        expression.insert(index-1, 1, result);  
19:      }  
20:      return expression;  
21:    }  

Friday, October 2, 2015

[Leetcode] Move Zeroes, Solution

Given an array nums, write a function to move all 0's to the end of it while maintaining the relative order of the non-zero elements.
For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0].
Note:
  1. You must do this in-place without making a copy of the array.
  2. Minimize the total number of operations.

[Thoughts]
典型的双指针问题。使用两个指针遍历数组,一个指向数值为0的元素,另一个指向数值不为0的元素,在遍历的过程中,不断交换两个指针的值。

例如,

比较简单的一道题。

[Code]
1:  class Solution {  
2:  public:  
3:    void moveZeroes(vector<int>& nums) {  
4:      for(int zero_index = 0, none_zero_index = 0;  
5:        none_zero_index < nums.size() && zero_index < nums.size();   
6:      ) {  
7:        if(nums[zero_index] != 0) {  
8:          zero_index++;  
9:          none_zero_index = zero_index;  
10:          continue;  
11:        }   
12:        if(nums[none_zero_index] == 0) {  
13:          none_zero_index++;  
14:          continue;  
15:        }  
16:        int temp = nums[zero_index];  
17:        nums[zero_index] = nums[none_zero_index];  
18:        nums[none_zero_index] = temp;  
19:        zero_index++;  
20:        none_zero_index++;  
21:      }  
22:    }  
23:  };  

git: https://github.com/codingtmd/leetcode/blob/master/src/Move_Zeroes.cpp




[Leetcode] Find the Duplicate Number, Solution

Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.
Note:
  1. You must not modify the array (assume the array is read only).
  2. You must use only constant, O(1) extra space.
  3. Your runtime complexity should be less than O(n2).
  4. There is only one duplicate number in the array, but it could be repeated more than once.

[Thoughts]
这题想清楚了就不难,想不清楚就麻烦。

假设数组A长度是n, 里面存储1到n的整数,那么很清楚,我们可以在按照A[i] = i+1,进行排序。但是现在有n+1个整数,而且至少有一个数字存在冗余。如果我们仍然按照A[i] = i+1来排序数组的话,那么当发现A[i]上已经是i+1的值时,说明我们已经找到了冗余数了。

举个例子,


简单的说,就是遍历数组的同时,按照A[i]应该放到A[A[i]]原则,进行swap,第一个无法swap的数字就是所求。


[Code]
1:  class Solution {  
2:  public:  
3:    int findDuplicate(vector<int>& nums) {  
4:      int length = nums.size();  
5:      for(int i =0; i< length; i++) {  
6:        if(nums[i] == i+1) {  
7:          continue;  
8:        }  
9:        int oldIndex = i;  
10:        int newIndex = nums[i]-1;  
11:        while(nums[oldIndex] != oldIndex +1 ) {  
12:          if(nums[oldIndex] == nums[newIndex] ) {  
13:            return nums[oldIndex];  
14:          }  
15:          int temp = nums[newIndex];  
16:          nums[newIndex] = nums[oldIndex];  
17:          nums[oldIndex] = temp;  
18:          newIndex = nums[oldIndex] -1;  
19:        }  
20:      }  
21:    }  
22:  };  

github: https://github.com/codingtmd/leetcode/blob/master/src/Find_the_Duplicate_Number.cpp


Monday, January 7, 2013

[LeetCode] Substring with Concatenation of All Words 解题报告


You are given a string, S, and a list of words, L, that are all of the same length. Find all starting indices of substring(s) in S that is a concatenation of each word in L exactly once and without any intervening characters.
For example, given:
S"barfoothefoobarman"
L["foo", "bar"]
You should return the indices: [0,9].
(order does not matter).
» Solve this problem

[解题思路]
没想出什么太好的办法,猜测这题应该是一道实现题。用两个map来统计字符串的出现次数,然后从左往右扫描主字符串。


[Code]
1:    vector<int> findSubstring(string S, vector<string> &L) {  
2:      // Start typing your C/C++ solution below  
3:      // DO NOT write int main() function  
4:      map<string, int> expectCount;  
5:      map<string, int> realCount;  
6:      for(int i =0; i< L.size(); i++)  
7:      {  
8:        expectCount[L.at(i)]++;  
9:      }  
10:      vector<int> result;  
11:      int row = L.size();  
12:      if(row ==0) return result;  
13:      int len = L[0].size();  
14:      for(int i =0; i< (int)S.size() - row*len+1; i++)  
15:      {  
16:        realCount.clear();  
17:        int j =0;  
18:        for(; j< row; j++)  
19:        {  
20:          string sub = S.substr(i+j*len, len);  
21:          if(expectCount.find(sub) != expectCount.end())  
22:          {  
23:            realCount[sub]++;  
24:          }  
25:          else  
26:            break;  
27:          if(realCount[sub] > expectCount[sub])  
28:          {  
29:            break;  
30:          }  
31:        }  
32:        if(j == row)  
33:          result.push_back(i);  
34:      }  
35:      return result;  
36:    }  

[注意]
Line 14 红字部分。如果S.size()是unsigned int,如果不先转换为int的话,计算结果会被promote成unsigned int。 比如 (unsigned int) 1 - (int)2, 最后的结果不是-1,而是4294967295。



Saturday, January 5, 2013

[LeetCode] Spiral Matrix 解题报告


Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.
For example,
Given the following matrix:
[
 [ 1, 2, 3 ],
 [ 4, 5, 6 ],
 [ 7, 8, 9 ]
]
You should return [1,2,3,6,9,8,7,4,5].
» Solve this problem

[解题思路]
递归式剥皮。首先剥掉最外面一层,然后递归调用剥剩余部分。 需要注意的是处理row_len和col_len为1 的情况。
这题主要是实现的难度,坐标的计算比较繁琐,算法上没有难度。

[Code]
1:    vector<int> spiralOrder(vector<vector<int> > &matrix) {  
2:      // Start typing your C/C++ solution below  
3:      // DO NOT write int main() function      
4:      vector<int> output;  
5:      int row_len = matrix.size();  
6:      if(row_len ==0) return output;  
7:      int col_len = matrix[0].size();  
8:      print_order(matrix, 0, row_len, 0, col_len, output);      
9:      return output;  
10:    }  
11:    void print_order(  
12:      vector<vector<int> > &matrix,  
13:      int row_s,  
14:      int row_len,  
15:      int col_s,  
16:      int col_len,  
17:      vector<int>& output)  
18:    {  
19:      if(row_len<=0 || col_len <=0) return;  
20:      if(row_len ==1)  
21:      {  
22:        for(int i =col_s; i< col_s+col_len; i++)  
23:          output.push_back(matrix[row_s][i]);          
24:        return;  
25:      }  
26:      if(col_len ==1)  
27:      {  
28:        for(int i =row_s; i<row_s + row_len; i++)  
29:          output.push_back(matrix[i][col_s]);          
30:        return;  
31:      }  
32:      for(int i =col_s; i<col_s+col_len-1; i++)  //up
33:        output.push_back(matrix[row_s][i]);  
34:      for(int i =row_s; i<row_s+row_len-1; i++)   //right
35:        output.push_back(matrix[i][col_s+col_len-1]);  
36:      for(int i =col_s; i<col_s+col_len-1; i++)  //bottom
37:        output.push_back(matrix[row_s+row_len-1][2*col_s+ col_len-1 -i]);  
38:      for(int i =row_s; i<row_s+row_len-1; i++)  //left
39:        output.push_back(matrix[2*row_s+row_len-1-i][col_s]);  
40:      print_order(matrix, row_s+1, row_len-2, col_s+1, col_len-2, output);  
41:    }  


Update 2014/01/05
想了一下,递归的解法看起来还是费劲,尤其是下标的计算,很繁琐。改一下,不用递归,在一个循环里面解决,提高一下可读性。


 1 vector<int> spiralOrder(vector<vector<int> > &matrix) {
 2     vector<int> result;
 3     int row = matrix.size();
 4     if(row == 0) return result;
 5     int col = matrix[0].size();
 6     if(col == 0) return result;
 7 
 8     //define the step for 4 directions
 9     int x[4] = { 1, 0, -1, 0 };
10     int y[4] = { 0, 1, 0, -1 };
11 
12     int visitedRows = 0;
13     int visitedCols = 0;
14 
15     // define direction: 0 means up, 1 means down, 2 means left, 3 means up
16     int direction = 0;
17     int startx = 0, starty = 0;
18     int candidateNum = 0, moveStep = 0;
19     while (true)
20     {
21         if (x[direction] == 0) // visit y axis
22         candidateNum = row - visitedRows;
23         else // visit x axis
24         candidateNum = col - visitedCols;
25         
26         if (candidateNum <= 0)  
27         break;
28         result.push_back(matrix[starty][startx]);
29         moveStep++;
30         if (candidateNum == moveStep) // change direction            
31         {
32             visitedRows += x[direction] == 0 ? 0 : 1;
33             visitedCols += y[direction] == 0 ? 0 : 1;
34             direction = (direction + 1) % 4;
35             moveStep = 0;
36         }
37         startx += x[direction];
38         starty += y[direction];
39     }
40     return result;
41 }

[LeetCode] Sort Colors 解题报告


Given an array with n objects colored red, white or blue, sort them so that objects of the same color are adjacent, with the colors in the order red, white and blue.
Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively.
Note:
You are not suppose to use the library's sort function for this problem.
Follow up:
A rather straight forward solution is a two-pass algorithm using counting sort.
First, iterate the array counting number of 0's, 1's, and 2's, then overwrite array with total number of 0's, then 1's and followed by 2's.
Could you come up with an one-pass algorithm using only constant space?
» Solve this problem

[解题思路]
一开始想到的就是计数排序,但是计数排序需要两边扫描,第一遍统计红,白,蓝的数目,第二遍生成新数组。

考虑到题目要求one pass。这就意味着类似于链表的双指针问题,这里也要track两个index,一个是red的index,一个是blue的index,两边往中间走。

i从0到blue index扫描,
遇到0,放在red index位置,red index后移;
遇到2,放在blue index位置,blue index前移;
遇到1,i后移。
扫描一遍得到排好序的数组。时间O(n),空间O(1),

[Code]
two-pass solution, Counting sort solution
1:       void sortColors(int A[], int n) {   
2:            // Start typing your C/C++ solution below   
3:            // DO NOT write int main() function   
4:            int red=0, white =0, blue=0;   
5:            for(int i =0; i < n; i++)   
6:            {   
7:                 switch(A[i])   
8:                 {   
9:                 case 0:   
10:                      red++;break;   
11:                 case 1:    
12:                      white++;break;   
13:                 case 2:   
14:                      blue++;break;   
15:                 }   
16:            }   
17:            for(int i =0; i<n; i++)   
18:            {   
19:                 if(red>0)   
20:                 {   
21:                      A[i]=0;   
22:                      red--;   
23:                      continue;   
24:                 }   
25:                 if(white>0)   
26:                 {   
27:                      A[i] =1;   
28:                      white--;   
29:                      continue;   
30:                 }   
31:                 A[i]=2;   
32:            }   
33:       }   


one-pass, two pointers solution
1:       void sortColors(int A[], int n) {   
2:            // Start typing your C/C++ solution below   
3:            // DO NOT write int main() function   
4:            int redSt=0, bluSt=n-1;   
5:            int i=0;   
6:            while(i<bluSt+1)   
7:            {   
8:                 if(A[i]==0)   
9:                 {   
10:                      std::swap(A[i],A[redSt]);   
11:                      redSt++;   
12:                      i++;   
13:                      continue;   
14:                 }   
15:                 if(A[i] ==2)   
16:                 {   
17:                      std::swap(A[i],A[bluSt]);   
18:                      bluSt--;    
19:                      continue;   
20:                 }   
21:                 i++;   
22:            }   
23:       }   


[LeetCode] Simplify Path 解题报告


Given an absolute path for a file (Unix-style), simplify it.
For example,
path = "/home/", => "/home"
path = "/a/./b/../../c/", => "/c"
Corner Cases:
  • Did you consider the case where path = "/../"?
    In this case, you should return "/".
  • Another corner case is the path might contain multiple slashes '/' together, such as "/home//foo/".
    In this case, you should ignore redundant slashes and return "/home/foo".
» Solve this problem

[解题思路]
利用栈的特性,如果sub string element
1. 等于“/”,跳过,直接开始寻找下一个element
2. 等于“.”,什么都不需要干,直接开始寻找下一个element
3. 等于“..”,弹出栈顶元素,寻找下一个element
4. 等于其他,插入当前elemnt为新的栈顶,寻找下一个element

最后,再根据栈的内容,重新拼path。这样可以避免处理连续多个“/”的问题。


[Code]
1:       string simplifyPath(string path) {   
2:            // Start typing your C/C++ solution below   
3:            // DO NOT write int main() function   
4:            vector<string> stack;   
5:            assert(path[0]=='/');   
6:            int i=0;   
7:            while(i< path.size())   
8:            {   
9:                 while(path[i] =='/' && i< path.size()) i++; //skip the begining '////'  
10:                 if(i == path.size())   
11:                      break;   
12:                 int start = i;   
13:                 while(path[i]!='/' && i< path.size()) i++; //decide the end boundary  
14:                 int end = i-1;   
15:                 string element = path.substr(start, end-start+1);   
16:                 if(element == "..")   
17:                 {   
18:                      if(stack.size() >0)   
19:                      stack.pop_back();   
20:                 }   
21:                 else if(element!=".")   
22:                 stack.push_back(element);      
23:            }   
24:            if(stack.size() ==0) return "/";   
25:            string simpPath;   
26:            for(int i =0; i<stack.size(); i++)   
27:            simpPath += "/" + stack[i];   
28:            return simpPath;   
29:       }   




[LeetCode] 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.
Follow up:
Did you use extra space?
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?
» Solve this problem

[解题思路]
非常无聊的一道题。解题点就在于清空标志位存在哪里的问题。可以创建O(m+n)的数组来存储,但此题是希望复用已有资源。这里可以选择第一行和第一列来存储标志位。

1.先确定第一行和第一列是否需要清零
2.扫描剩下的矩阵元素,如果遇到了0,就将对应的第一行和第一列上的元素赋值为0
3.根据第一行和第一列的信息,已经可以讲剩下的矩阵元素赋值为结果所需的值了
4.根据1中确定的状态,处理第一行和第一列。





[Code]
1:    void setZeroes(vector<vector<int> > &matrix) {  
2:      // Start typing your C/C++ solution below  
3:      // DO NOT write int main() function  
4:      assert(matrix.size()>0);  
5:      int row = matrix.size(), col = matrix[0].size();  
6:      bool zerorow=false, zerocol=false;  
7:      for(int i = 0; i< col; i++)  
8:        if(matrix[0][i] ==0)  
9:          zerorow = 1;  
10:      for(int i = 0; i< row; i++)  
11:        if(matrix[i][0] ==0)  
12:          zerocol=1;  
13:      for(int i =1; i < row; i++)  
14:        for(int j = 1; j<col; j++)  
15:          if(matrix[i][j] ==0)  
16:          {  
17:            matrix[0][j] =0;  
18:            matrix[i][0] =0;  
19:          }  
20:      for(int i =1; i < row; i++)  
21:        for(int j = 1; j<col; j++)  
22:          if(matrix[i][0] ==0 || matrix[0][j] ==0)  
23:            matrix[i][j] =0;  
24:      if(zerorow ==1)  
25:        for(int i =0; i< col; i++)  
26:          matrix[0][i] =0;  
27:      if(zerocol==1)  
28:        for(int i =0; i< row; i++)  
29:          matrix[i][0] =0;          
30:    }  




Tuesday, January 1, 2013

[LeetCode] Rotate Image 解题报告


You are given an n x n 2D matrix representing an image.
Rotate the image by 90 degrees (clockwise).
Follow up:
Could you do this in-place?
» Solve this problem

[解题思路]
如下图,首先沿逆对角线翻转一次,然后按x轴中线翻转一次。

[Code]
1:    void rotate(vector<vector<int> > &matrix) {  
2:      // Start typing your C/C++ solution below  
3:      // DO NOT write int main() function  
4:      int len = matrix[0].size();  
5:      for(int i =0; i<len-1; i++)  
6:      {  
7:        for(int j=0;j<len-i;j++)  
8:        {  
9:          swap(matrix[i][j], matrix[len-1-j][len-1-i]);  
10:        }  
11:      }  
12:      for(int i =0; i<len/2; i++)  
13:      {  
14:        for(int j=0;j<len;j++)  
15:        {  
16:          swap(matrix[i][j], matrix[len-i-1][j]);  
17:        }  
18:      }  
19:    }  
20:    void swap(int& a1, int&a2)  
21:    {  
22:      int temp = a1;  
23:      a1=a2;  
24:      a2=temp;  
25:    }  



Wednesday, December 26, 2012

[LeetCode] Merge Sorted Array 解题思路


Given two sorted integer arrays A and B, merge B into A as one sorted array.
Note:
You may assume that A has enough space to hold additional elements from B. The number of elements initialized in A and B are m and n respectively.
» Solve this problem

[解题思路]
从后往前填空。


[Code]
1:    void merge(int A[], int m, int B[], int n) {  
2:      // Start typing your C/C++ solution below  
3:      // DO NOT write int main() function  
4:      int k = m+n-1;  
5:      int i = m-1, j =n-1;  
6:      for(; i>=0 && j>=0; k--)  
7:      {  
8:        if(A[i] >= B[j])  
9:        {  
10:          A[k] = A[i];  
11:          i--;  
12:        }  
13:        else  
14:        {  
15:          A[k] = B[j];  
16:          j--;  
17:        }  
18:      }  
19:      while(j >=0)  
20:      {  
21:        A[k] = B[j];  
22:        k--; j--;  
23:      }  
24:    }  




Friday, December 21, 2012

[LeetCode] First Missing Positive 解题报告


Given an unsorted integer array, find the first missing positive integer.
For example,
Given [1,2,0] return 3,
and [3,4,-1,1] return 2.
Your algorithm should run in O(n) time and uses constant space.
» Solve this problem

[解题思路]
其实就是桶排序,只不过不许用额外空间。所以,每次当A[i]!= i的时候,将A[i]与A[A[i]]交换,直到无法交换位置。终止条件是 A[i]== A[A[i]]。
然后i -> 0 到n走一遍就好了。

[Code]

1:   int firstMissingPositive(int A[], int n) {  
2:      // Start typing your C/C++ solution below  
3:      // DO NOT write int main() function  
4:      int i =0;  
5:      for(int i =0; i< n; i++)  
6:      {  
7:        while(A[i] != i+1)  
8:        {        
9:          if(A[i] <= 0 || A[i] >n || A[i] == A[A[i] -1]) break;  
10:          int temp = A[i];  
11:          A[i] = A[temp-1];  
12:          A[temp-1] = temp;          
13:        }  
14:      }  
15:      for(int i =0; i< n; i++)  
16:       if(A[i]!=i+1)  
17:        return i+1;  
18:      return n+1;  
19:    }  

[注意]
题目说清楚了,很简单,但是实现起来还是有些细节比较烦人。首先,不能按照A[i] = i来存,因为题目要求寻找正数,如果A[0]用来存储0的话,会影响数据处理。比如当A = {1}的时候,如果A[0] = 0的话,根本没地方存1的值了。所以正确的存储方式应该是A[i]= i+1.
但是由此带来的是,Line 7, 9, 11, 12, 16, 17都需要更改,以反映出这种映射。
还有一点容易遗忘的就是Line18,如果当前数组找不到目标值的话,那么目标值就应该是n+1.这个容易漏了。