LeetCodeDay05

2018-04-13  本文已影响0人  GoMomi

1. 两数之和

描述
示例
思路

1、暴力法,依次遍历,时间复杂度O(n^2)
2、通过一个Map来保存下标和值,然后遍历一次数组,找target-val的值,存在就找到了,时间复杂度O(n),空间复杂度O(n)

class Solution_01_01 {
 public:
  vector<int> twoSum(vector<int>& nums, int target) {
    vector<int> result;
    bool brk = false;
    for (int i = 0; i < nums.size(); i++) {
      for (int j = i + 1; j < nums.size(); j++) {
        if (nums[i] + nums[j] == target) {
          result.push_back(i);
          result.push_back(j);
          brk = true;
          break;
        }
      }
      if (brk) break;
    }
    return result;
  }
};

class Solution_01_02 {
 public:
  vector<int> twoSum(vector<int>& nums, int target) {
    vector<int> result;
    unordered_map<int, int> hash;
    for (int i = 0; i < nums.size(); i++) {
      if (hash.find(target - nums[i]) != hash.end()) {
        result.push_back(hash[target - nums[i]]);
        result.push_back(i);
        break;
      }
      hash.insert({nums[i], i});
    }
    return result;
  }
};

// 和上面思路相同,但实现起来更酷的一种写法
class Solution_01_03 {
 public:
  vector<int> twoSum(vector<int>& nums, int target) {
    unordered_map<int, int> m;
    for (int i = 0; i < nums.size(); ++i) {
      if (m.count(target - nums[i])) {
        return {i, m[target - nums[i]]};
      }
      m[nums[i]] = i;
    }
    return {};
  }
};

36. 有效的数独

描述
说明
思路
  1. 对于比价抽象的问题,采取拟人法求解。想想如果是人为来判断是如何进行的。一个数独要合理,需要的是3个条件,该行只有1-9,该列只有1-9,该数字所处小9宫格只有1-9。模拟人为判断的情形,转换过来就是该数这一行没有重复、这一列没有重复、小九宫格没有重复,则这一格是OK的。依次遍历每一格,都OK则数独是有效的。
  2. 解法二则是利用空间换时间。避免了每个val都要把行列和小9宫格遍历一遍。利用一个set保存元素出现的次数。在遍历的时候对应位置+1,当其>1时返回false。先检查所有行,再检查所有列,最后检查9个小9宫格。
class Solution_36_01 {
 public:
  bool isValidSudoku(vector<vector<char>>& board) {
    if (board.empty()) return false;
    for (int row = 0; row < 9; row++) {
      for (int col = 0; col < 9; col++) {
        if (!isValidVal(board, row, col)) return false;
      }
    }
    return true;
  }
  bool isValidVal(vector<vector<char>>& board, int row, int col) {
    char val = board[row][col];
    // 这一列不能有val
    for (int i = 1; i < 9; i++) {
      char cur = board[(row + i) % 9][col];
      if (cur != '.' && cur == val) return false;
    }
    // 这一行不能有val
    for (int i = 1; i < 9; i++) {
      char cur = board[row][(col + i) % 9];
      if (cur != '.' && cur == val) return false;
    }
    // 小的九宫格不能有val
    int startRow = row / 3 * 3;
    int startCol = col / 3 * 3;
    for (int i = 0; i < 3; i++) {
      for (int j = 0; j < 3; j++) {
        int curRow = startRow + i;
        int curCol = startCol + j;
        char cur = board[curRow][curCol];
        if (cur != '.' && cur == val && (curRow != row || curCol != col)) {
          return false;
        }
      }
    }
    return true;
  }
};

class Solution {
 public:
  bool isValidSudoku(const vector<vector<char>>& board) {
    bool used[9];
    for (int i = 0; i < 9; i++) {
      // 检查行
      fill(used, used + 9, false);
      for (int j = 0; j < 9; j++) {
        if (!check(board[i][j], used)) {
          return false;
        }
      }
      // 检查列
      fill(used, used + 9, false);
      for (int j = 0; j < 9; j++) {
        if (!check(board[j][i], used)) {
          return false;
        }
      }
    }
    // 检查9个子格子
    for (int i = 0; i < 3; i++)
      for (int j = 0; j < 3; j++) {
        fill(used, used + 9, false);
        for (int row = i * 3; row < i * 3 + 3; row++) {
          for (int col = j * 3; col < j * 3 + 3; col++) {
            if (!check(board[row][col], used)) {
              return false;
            }
          }
        }
      }
    return true;
  }
  bool check(char ch, bool used[]) {
    if (ch == '.') return true;
    if (used[ch - '1']) return false;
    return used[ch - '1'] = true;
  }
};
上一篇 下一篇

猜你喜欢

热点阅读