思路:hash
class Solution:
def findRepeatNumber(self, nums: List[int]) -> int:
dict_ = dict()
for i in range(len(nums)):
if nums[i] in dict_:
return nums[i]
else:
dict_[nums[i]] = i
class Solution {
public:
int findRepeatNumber(vector<int>& nums) {
unordered_map<int, int> dict_;
for(int i = 0; i < nums.size(); i++){
dict_[nums[i]]++;
if(dict_[nums[i]]>1){
return nums[i];
}
}
return 0;
}
};
class Solution:
def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool:
h = len(matrix)
if h == 0:
return False
w = len(matrix[0])
i, j = h-1, 0
while i >= 0 and j <= w-1:
if matrix[i][j] > target:
i -= 1
elif matrix[i][j] < target:
j += 1
else:
return True
return False
c++实现:
class Solution {
public:
bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
if(matrix.size() == 0 || matrix[0].size() == 0){return false;}
int h = matrix.size();
int w = matrix[0].size();
int i = h-1, j = 0;
while(i >= 0 && j <= w-1){
if(matrix[i][j] > target){
i--;
}
else if(matrix[i][j] < target){
j++;
}
else{
return true;
}
}
return false;
}
};
class Solution:
def replaceSpace(self, s: str) -> str:
return s.replace(' ', '%20')
c++实现:
class Solution {
public:
string replaceSpace(string s) {
string res = "";
for(int i = 0; i < s.size(); i++){
if(s[i]==' '){
res += "%20";
}
else{
res += s[i];
}
}
return res;
}
};
优化:直接原地修改思路:双指针法,resize出新的字符长度,当i,j相等时说明找到的都是非空格的此时跳出循环.
class Solution {
public:
string replaceSpace(string s) {
int blank = 0;
int s_ori_length = s.size();
for(int i = 0; i<s.size(); i++){
if(s[i] == ' '){
blank++;
}
}
s.resize(s.size() + blank * 2);
int s_new_length = s.size();
//相等就跳出
for(int i = s_new_length - 1, j = s_ori_length - 1; j < i; i--, j-- ){
if(s[j] != ' '){
s[i] = s[j];
}else{
s[i - 2] = '%';
s[i - 1] = '2';
s[i] = '0';
i -= 2;
}
}
return s;
}
};
方法1:利用栈
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def reversePrint(self, head: ListNode) -> List[int]:
# if head:
# return self.reversePrint(head.next)+[head.val]
# else:
# return []
res = []
while head:
res.append(head.val)
head = head.next
return res[::-1]
方法2:递归回溯
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
void help(ListNode* node, vector<int>& res){
if(node == NULL){
return ;
}
help(node->next, res);
res.push_back(node->val);
}
vector<int> reversePrint(ListNode* head) {
vector<int> res;
help(head, res);
return res;
}
};
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
if len(preorder) == 0 or len(inorder) == 0:
return None
node = TreeNode(preorder[0])
middle_index = inorder.index(preorder[0])
node.left = self.buildTree(preorder[1:middle_index+1], inorder[:middle_index])
node.right = self.buildTree(preorder[middle_index+1:], inorder[middle_index+1:])
return node
c++实现:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(preorder.empty() || inorder.empty()){
return NULL;
}
int node_value = preorder[0];
int middle_index = 0;
for(int i = 0; i < inorder.size(); i++){
if(inorder[i] == node_value){
middle_index = i;
break;
}
}
TreeNode* node = new TreeNode(node_value);
vector<int> leftInorder(inorder.begin(), inorder.begin() + middle_index);
vector<int> rightInorder(inorder.begin() + middle_index + 1, inorder.end());
vector<int> leftPreorder(preorder.begin() + 1, preorder.begin() + middle_index + 1);
vector<int> rightPreorder(preorder.begin() + middle_index + 1, preorder.end());
node->left = buildTree(leftPreorder, leftInorder);
node->right = buildTree(rightPreorder, rightInorder);
return node;
}
};
python代码:
class CQueue:
def __init__(self):
self.stack_A = []
self.stack_B = []
def appendTail(self, value: int) -> None:
self.stack_A.append(value)
def deleteHead(self) -> int:
if len(self.stack_A) == 0 and len(self.stack_B) == 0:
return -1
if len(self.stack_B) == 0:
while(len(self.stack_A)):
temp = self.stack_A.pop()
self.stack_B.append(temp)
value = self.stack_B.pop()
return value
# Your CQueue object will be instantiated and called as such:
# obj = CQueue()
# obj.appendTail(value)
# param_2 = obj.deleteHead()
c++实现:
class CQueue {
public:
stack<int> stack_A;
stack<int> stack_B;
CQueue() {
}
void appendTail(int value) {
stack_A.push(value);
}
int deleteHead() {
if(stack_A.empty() && stack_B.empty()){
return -1;
}
if(stack_B.empty()){
while(!stack_A.empty()){
stack_B.push(stack_A.top());
stack_A.pop();
}
}
int value = stack_B.top();
stack_B.pop();
return value;
}
};
/**
* Your CQueue object will be instantiated and called as such:
* CQueue* obj = new CQueue();
* obj->appendTail(value);
* int param_2 = obj->deleteHead();
*/
python实现:
class Solution:
def numWays(self, n: int) -> int:
if n <= 1:
return 1
a, b = 1, 1
for i in range(2, n + 1):
temp = a
a = b
b = (temp + b) % 1000000007
return b
c++实现:
class Solution {
public:
int numWays(int n) {
if(n <= 1){
return 1;
}
int a = 1, b = 1;
for (int i = 2; i < n+1; i++){
int temp = a;
a = b;
b = (temp + b) % 1000000007;
}
return b;
}
};
python代码:
class Solution:
def minArray(self, numbers):
# return min(numbers)
left, right = 0, len(numbers) - 1
while left < right:
middle = left + (right - left) // 2
if numbers[middle] < numbers[right]:#说明middle是最小值右侧元素
right = middle
elif numbers[middle] > numbers[right]:#说明middle是最小值左侧元素
left = middle + 1
else:
right -= 1 #相当就没法判断 采取保守right-1即可
print('==left:', left)
print('===numbers[left]', numbers[left])
return numbers[left]
# numbers = [1, 2, 3, 4, 5]
# numbers = [3, 4, 5, 1, 2]
# numbers = [2, 2, 2, 0, 1]
# numbers = [2, 2, 2, 0, 1]
# numbers = [1, 3, 5]
numbers = [1, 3, 3]
# numbers = [3, 2, 1, 4, 5]
sol = Solution()
sol.minArray(numbers)
c++代码:
class Solution {
public:
int minArray(vector<int>& numbers) {
int left = 0;
int right = numbers.size() - 1;
while(left < right){
int middle = left + (right - left) / 2;
if(numbers[middle] < numbers[right]){
right = middle;
}
else if(numbers[middle] > numbers[right]){
left = middle + 1;
}
else{
right--;
}
}
return numbers[left];
}
};
思路:与岛屿,水塘类似,只不过添加一个回溯的过程,直接修改board即可,回溯出来还原即可
class Solution:
def help(self, i, j, h, w, index):
if i<0 or j<0 or i>=h or j>=w or self.word[index] != self.board[i][j]:
return False
if index == len(self.word) - 1:
return True
self.board[i][j] = ''#说明board和word找到相同的 因为不能重复 修改一下borad
for direction in self.directions:
new_i, new_j = direction[0] + i, direction[1] + j
if self.help(new_i, new_j, h, w, index + 1):
return True
self.board[i][j] = self.word[index]#回溯出去需要还原
return False
def exist(self, board: List[List[str]], word: str) -> bool:
self.board = board
self.word = word
self.directions = [(-1, 0), (0, -1), (1, 0), (0, 1)]
h = len(board)
w = len(board[0])
for i in range(h):
for j in range(w):
if self.help(i, j, h, w, 0):
return True
return False
c++实现:
class Solution {
public:
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, -1, 0, 1};
public:
bool help(int i, int j, int h, int w, vector<vector<char>>& board, string word, int index){
if(i < 0 || i >= h || j < 0 || j >= w || board[i][j] != word[index]){
return false;
}
if (index == word.size() - 1){
return true;
}
board[i][j] = '#';
for(int k = 0; k < 4; k++){
int new_i = dx[k] + i;
int new_j = dy[k] + j;
if(help(new_i, new_j, h, w, board, word, index + 1)){
return true;
}
}
board[i][j] = word[index];
return false;
}
bool exist(vector<vector<char>>& board, string word) {
int h = board.size();
int w = board[0].size();
for(int i = 0; i<h; i++){
for (int j = 0; j < w; j++){
if (help(i, j, h, w, board, word, 0)){
return true;
}
}
}
return false;
}
};
思路1:bfs 只需要判断右边和下边,因为上边和左边已经遍历过了
class Solution:
def digitSum(self, num):
count = 0
while num:
count += num % 10
num //= 10
return count
def movingCount(self, m: int, n: int, k: int) -> int:
#BFS
queue = [(0, 0)]
res = set()
while len(queue):
x, y = queue.pop()
#满足搜索条件
if (x,y) not in res and 0<=x<m and 0<=y<n and (self.digitSum(x) + self.digitSum(y)) <= k:
res.add((x,y))
for (x_, y_) in ((x+1, y), (x, y+1)):
queue.append((x_, y_))
return len(res)
思路2:递推
view[i][j] = view[i-1][j] or view[j][j-1]
class Solution:
def digitSum(self, num):
count = 0
while num:
count += num % 10
num //=10
return count
def movingCount(self, m: int, n: int, k: int) -> int:
#递推
view = set([(0, 0)])
for i in range(m):
for j in range(n):
if ((i - 1, j) in view or (i, j - 1) in view) and (self.digitSum(i) + self.digitSum(j)) <= k:
view.add((i, j))
return len(view)
对于c++不存在列表in的关系,需要换种写法
class Solution {
public:
int digitSum(int num){
int count = 0;
while(num){
count += num % 10;
num /= 10;
}
return count;
}
int movingCount(int m, int n, int k) {
vector<vector<int>> view(m, vector<int>(n, 0));
view[0][0] = 1;
int res = 0;
for (int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
if ((digitSum(i)+digitSum(j))>k){
continue;
}
if(i-1 >= 0){
view[i][j] |= view[i-1][j];
}
if(j-1 >= 0){
view[i][j] |= view[i][j-1];
}
res += view[i][j];
}
}
return res;
}
};
思路:
python:
class Solution:
def cuttingRope(self, n: int) -> int:
if(n == 2):
return 1
if(n == 3):
return 2
res = 1
while(n > 4):
res *= 3
n -= 3
res *= n
return res
c++:
class Solution {
public:
int cuttingRope(int n) {
if(n == 2){
return 1;
}
if(n == 3){
return 2;
}
int res = 1;
while(n > 4){
res *= 3;
n -= 3;
}
res *= n;
return res;
}
};
思路:
尽可能将绳子以长度 33 等分为多段时,乘积最大,原因为https://leetcode-cn.com/problems/jian-sheng-zi-ii-lcof/solution/mian-shi-ti-14-ii-jian-sheng-zi-iitan-xin-er-fen-f/
class Solution:
def cuttingRope(self, n: int) -> int:
if n == 2:
return 1
if n == 3:
return 2
res = 1;
while n > 4:
res *= 3
res %= 1000000007
n -= 3
res *= n
res %= 1000000007
return res
c++代码:
class Solution {
public:
int cuttingRope(int n) {
if(n == 2){
return 1;
}
if(n == 3){
return 2;
}
long res = 1;
while(n > 4){
res *= 3;
res %= 1000000007 ;
n -= 3;
}
res *= n;
res %= 1000000007 ;
return res;
}
};
思路:一种是通过右移,一种是通过n&n-1不断减少1
python:
class Solution:
def hammingWeight(self, n: int) -> int:
res = 0
while n:
if n & 1:
res += 1
n >>= 1
return res
c++实现:通过右移
class Solution {
public:
int hammingWeight(uint32_t n) {
int res = 0;
while(n){
if(n & 1){
res++;
}
n >>= 1;
}
return res;
}
};
c++实现: 通过n&=n-1
class Solution {
public:
int hammingWeight(uint32_t n) {
int res = 0;
while(n){
res++;
n &= n - 1;
}
return res;
}
};
思路:递归,注意分正负和奇数偶数即可
class Solution:
def help(self, x, n):
if x == 0:
return 0
if n == 0:
return 1
if n == 1:
return x
temp = self.help(x, n//2)
if n % 2 == 1:
return temp * temp * x
else:
return temp * temp
def myPow(self, x: float, n: int) -> float:
if n > 0:
return self.help(x, n)
else:
return 1 / self.help(x, -n)
c++实现:
class Solution {
public:
double help(double x, long n){
if(x == 0 || x == 1){
return x;
}
if(n == 0){
return 1;
}
if(n == 1){
return x;
}
double temp = help(x, n/2);
if(n % 2 == 1){
return temp * temp * x;
}
else{
return temp * temp;
}
}
double myPow(double x, long n) {
if(n > 0){
return help(x, n);
}
else{
return 1./help(x, -n);
}
}
};
思路:如果没有考虑大数的话直接for循环就行
class Solution:
def printNumbers(self, n: int) -> List[int]:
self.res = []
for m in range(1, 10**n):
self.res.append(m)
return self.res
考虑大数的做法,递归回溯,用字符串相加的方式就避免了数字超过范围
class Solution:
def backtrace(self, count, track, length):
if count == length:#终止条件 位数为length
self.res.append(int(''.join(track)))
return
for i in range(10):
store = track.copy()
track.append(str(i))
self.backtrace(count + 1, track, length)
track = store
def printNumbers(self, n: int) -> List[int]:
self.res = []
for m in range(1, n + 1):
for start_num in range(1, 10):
track = [str(start_num)]
self.backtrace(1, track, m)
return self.res
c++实现:
class Solution {
public:
vector<int> res;
void backtrace(int count, vector<char> track, int length){
if(count == length){//长度相同 出去
string temp_str = "";
for (int i = 0; i < track.size(); i++){
temp_str += track[i];
}
int int_str = atoi(temp_str.c_str());
res.push_back(int_str);
return ;
}
for(int i=0; i<10; i++){
vector<char> store(track);
track.push_back(i + '0');
backtrace(count + 1, track, length);
track = store;
}
}
vector<int> printNumbers(int n) {
for(int m = 1; m < n+1; m++){
for (int start_num = 1; start_num<10; start_num++){
vector<char> track(1, start_num + '0');
backtrace(1, track, m);
}
}
return res;
}
};
思路:双指针
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def deleteNode(self, head: ListNode, val: int) -> ListNode:
if head is None:
return head
new_head = ListNode(0)
new_head.next = head
pre = new_head
cur = head
while cur.val != val:
pre = cur
cur = cur.next
pre.next = cur.next
return new_head.next
c++实现:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* deleteNode(ListNode* head, int val) {
if(head == NULL){
return NULL;
}
ListNode* new_head = new ListNode(0);
new_head->next = head;
ListNode* pre = new_head;
ListNode* cur = head;
while(cur->val != val){
pre = cur;
cur = cur->next;
}
pre->next = cur->next;
return new_head->next;
}
};
c++递归:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* deleteNode(ListNode* head, int val) {
if(head == NULL){
return NULL;
}
if(head->val == val){
return head->next;
}
head->next = deleteNode(head->next, val);
return head;
}
};
思路:
class Solution:
def matches(self, i, j, s, p):
if i == 0:
return False
if p[j - 1] == '.':
return True
return s[i - 1] == p[j - 1]
def isMatch(self, s: str, p: str) -> bool:
m, n = len(s), len(p)
dp = [[False] * (n + 1) for _ in range(m + 1)]
dp[0][0] = True
for i in range(m + 1):
for j in range(1, n + 1):
if p[j - 1] == '*':
dp[i][j] |= dp[i][j - 2]
if self.matches(i, j - 1, s, p):
dp[i][j] |= dp[i - 1][j]
else:
if self.matches(i, j, s, p):
dp[i][j] |= dp[i - 1][j - 1]
return dp[-1][-1]
c++:
class Solution {
public:
bool help(int i, int j, string s, string p){
if(i == 0){
return false;
}
if(p[j-1] == '.'){
return true;
}
return s[i-1] == p[j-1];
}
bool isMatch(string s, string p) {
int m = s.size();
int n = p.size();
vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));
dp[0][0] = 1;
for(int i = 0; i < m + 1; i++){
for (int j = 1; j < n + 1; j++){
if(p[j-1] == '*'){
dp[i][j] |= dp[i][j-2];
if(help(i, j-1, s, p)){
dp[i][j] |= dp[i-1][j];
}
}
else{
if (help(i, j, s, p)){
dp[i][j] |= dp[i-1][j-1];
}
}
}
}
return dp[m][n];
}
};
python:
class Solution:
def isNumber(self, s: str) -> bool:
try:
float(s)
except Exception as e:
print('==error:',e)
return False
return True
c++实现:
class Solution {
public:
bool isNumber(string s) {
if(s.empty()) return false;
while(s.length() > 0 && s[0] == ' ') s.erase(0, 1);
while(s.length() > 0 && s[s.length() - 1] == ' ') s.erase(s.length() - 1, 1);
if(s.length() == 0) return false;
bool isDot = false, isE = false, isNumber = false;
for(int i=0; i<s.length(); ++i)
{
if(s[i] >= '0' && s[i] <= '9')
isNumber = true;
else if(s[i] == 'e' || s[i] == 'E')
{
if(isE || !isNumber || i == s.length() - 1) return false;
s[i] = 'e'; // 将'E'变成'e'
isE = true;
}
else if(s[i] == '+' || s[i] == '-')
{
if((i > 0 && s[i - 1] != 'e') || (i == s.length() - 1)) return false;
}
else if(s[i] == '.')
{
if(isDot || isE || (i == s.length() - 1 && !isNumber)) return false;
isDot = true;
}
else return false;
}
return true;
}
};
思路:双指针 奇数放左边 偶数放右边
class Solution:
def exchange(self, nums: List[int]) -> List[int]:
left = 0
right = len(nums) - 1
while left<right:
if nums[left]%2:#奇数左指针就一直右移
left += 1
continue
if nums[right]%2 == 0:#偶数右指针就一直左移
right -= 1
continue
nums[left], nums[right] = nums[right],nums[left]
return nums
c++实现:
class Solution {
public:
void swap(int &a, int &b){
int temp = a;
a = b;
b = temp;
}
vector<int> exchange(vector<int>& nums) {
int left = 0, right = nums.size() - 1;
while(left < right){
if(nums[left] % 2){
left++;
continue;
}
if(nums[right] % 2 == 0){
right--;
continue;
}
swap(nums[left], nums[right]);
}
return nums;
}
};
思路:双指针
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def getKthFromEnd(self, head: ListNode, k: int) -> ListNode:
node_A = head
node_B = head
while k:
node_A = node_A.next
k -= 1
while node_A:
node_A = node_A.next
node_B = node_B.next
return node_B
c++实现:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* getKthFromEnd(ListNode* head, int k) {
ListNode* node_A = head;
ListNode* node_B = head;
while(k>0){
node_A = node_A->next;
k--;
}
while(node_A != NULL){
node_A = node_A->next;
node_B = node_B->next;
}
return node_B;
}
};
python代码:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
pre = None
cur = head
while cur:
temp = cur.next
cur.next = pre
pre = cur
cur = temp
return pre
c++实现:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* pre = NULL;
ListNode* cur = head;
while(cur){
ListNode* temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
}
return pre;
}
};
python:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
fake_head_node = ListNode(0)
cur = fake_head_node
while l1 and l2:
if l1.val<l2.val:
cur.next = l1
l1 = l1.next
else:
cur.next = l2
l2 = l2.next
cur = cur.next
if l1:
cur.next = l1
else:
cur.next = l2
return fake_head_node.next
c++:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode* new_head = new ListNode(0);
ListNode* node = new_head;
while(l1!=NULL && l2 !=NULL){
if(l1->val<l2->val){
node->next = l1;
l1 = l1->next;
}
else{
node->next = l2;
l2 = l2->next;
}
node = node->next;
}
if (l1!=NULL){
node->next = l1;
}
if(l2!=NULL){
node->next = l2;
}
return new_head->next;
}
};
思路:
B为空 说明B已经遍历完成
A为空或者A, B两个节点的值不相等则返回false
对A和B节点进行递归调用 对A的左右子节点分别进行递归调用 可能A的子结构等于B的在深处
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def help(self, A, B):
if B is None:#B为空 说明B已经遍历完成
return True
if (A is None) or (A.val != B.val):#A为空或者A, B两个节点的值不相等则返回false
return False
return self.help(A.left, B.left) and self.help(A.right, B.right)
def isSubStructure(self, A: TreeNode, B: TreeNode) -> bool:
if A is None or B is None:
return False
#对A和B节点进行递归调用 对A的左右子节点分别进行递归调用 可能A的子结构在深处
return self.help(A, B) or self.isSubStructure(A.left, B) or self.isSubStructure(A.right, B)
c++实现:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool help(TreeNode* A, TreeNode* B){
if(B == NULL){
return true;
}
if((A == NULL) || (A->val != B->val)){
return false;
}
return help(A->left, B->left) && help(A->right, B->right);
}
bool isSubStructure(TreeNode* A, TreeNode* B) {
if(A == NULL || B == NULL){
return false;
}
return help(A, B) || isSubStructure(A->left, B) || isSubStructure(A->right, B);
}
};
思路;其实就是翻转二叉树,分别对左右子树进行交换,递归即可,出口是节点为none
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def mirrorTree(self, root: TreeNode) -> TreeNode:
if root is None:
return None
left = self.mirrorTree(root.left)
right = self.mirrorTree(root.right)
root.right = left
root.left = right
return root
c++实现:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* mirrorTree(TreeNode* root) {
if(root == NULL){
return root;
}
TreeNode* left = mirrorTree(root->left);
TreeNode* right = mirrorTree(root->right);
root->left = right;
root->right = left;
return root;
}
};
思路:递归判断左右子树是否相等,找准递归出口就行
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def help(self, node1, node2):
if node1 == None and node2 == None:
return True
if node1 == None or node2 == None:
return False
if node1.val != node2.val:
return False
return self.help(node1.left, node2.right) and self.help(node1.right, node2.left)
def isSymmetric(self, root: TreeNode) -> bool:
return self.help(root, root)
c++实现:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool help(TreeNode* node1, TreeNode* node2){
if(node1 == NULL && node2 == NULL){
return true;
}
if(node1 == NULL || node2 == NULL){
return false;
}
if(node1->val != node2->val){
return false;
}
return help(node1->left, node2->right) && help(node1->right, node2->left);
}
bool isSymmetric(TreeNode* root) {
return help(root, root);
}
};
思路:从外层到内层循环,终止条件就是左上角索引和右上角索引重合时
class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
h = len(matrix)
if h == 0:
return []
w = len(matrix[0])
left = 0
right = w - 1
top = 0
bottom = h - 1
res = []
while left<=right and top<=bottom:
for i in range(left, right + 1):
res.append(matrix[top][i])
for i in range(top + 1, bottom + 1):
res.append(matrix[i][right])
if left < right and top < bottom:
for i in range(right-1, left-1, -1):
res.append(matrix[bottom][i])
for i in range(bottom-1, top, -1):
res.append(matrix[i][left])
left+=1
right-=1
top+=1
bottom-=1
# print('==res:',res)
return res
c++实现:
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
vector<int> res;
int h = matrix.size();
if(h<1){
return res;
}
int w = matrix[0].size();
int left = 0, top = 0, right = w - 1, bottom = h - 1;
while (left <= right && top <= bottom){
for (int i = left; i < right+1; i++){
res.push_back(matrix[top][i]);
}
for (int i = top + 1; i < bottom + 1; i++){
res.push_back(matrix[i][right]);
}
if(left<right && top<bottom){
for (int i = right - 1; i > left-1; i--){
res.push_back(matrix[bottom][i]);
}
for (int i = bottom - 1; i > top; i--){
res.push_back(matrix[i][left]);
}
}
left++;
right--;
top++;
bottom--;
// cout<<"res:"<<res<<endl;
}
return res;
}
};
python:
class MinStack:
def __init__(self):
"""
initialize your data structure here.
"""
self.stack = []
def push(self, x: int) -> None:
self.stack.append(x)
def pop(self) -> None:
self.stack.pop()
def top(self) -> int:
return self.stack[-1]
def min(self) -> int:
return min(self.stack)
# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(x)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.min()
c++:
class MinStack {
public:
stack<int> stack_A;
stack<int> min_stack;
/** initialize your data structure here. */
MinStack() {
}
void push(int x) {
stack_A.push(x);
if(min_stack.empty() || min_stack.top()>=x){
min_stack.push(x);
}
}
void pop() {
if(stack_A.top() == min_stack.top()){
min_stack.pop();
}
stack_A.pop();
}
int top() {
return stack_A.top();
}
int min() {
return min_stack.top();
}
};
/**
* Your MinStack object will be instantiated and called as such:
* MinStack* obj = new MinStack();
* obj->push(x);
* obj->pop();
* int param_3 = obj->top();
* int param_4 = obj->min();
*/
思路:用栈 遇到相等的 就一直出栈
class Solution:
def validateStackSequences(self, pushed: List[int], popped: List[int]) -> bool:
stack = []
index = 0
for i in range(len(pushed)):
stack.append(pushed[i])
while stack and stack[-1]==popped[index]:
stack.pop()
index += 1
return not stack
c++实现:
class Solution {
public:
bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
stack<int> stack_A;
int index = 0;
for(int i=0; i<pushed.size(); i++){
stack_A.push(pushed[i]);
while(!stack_A.empty() && stack_A.top() == popped[index]){
index++;
stack_A.pop();
}
}
return stack_A.empty();
}
};
思路:bfs
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def levelOrder(self, root: TreeNode) -> List[int]:
res = []
if root is None:
return res
queue = [root]
while queue:
for i in range(len(queue)):
node = queue.pop(0)
res.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return res
c++实现:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> levelOrder(TreeNode* root) {
vector<int> res;
if(root == NULL){
return res;
}
queue<TreeNode*> queue_A;
queue_A.push(root);
while(!queue_A.empty()){
int count = queue_A.size();
for(int i=0; i<count; i++){
TreeNode* node = queue_A.front();
res.push_back(node->val);
queue_A.pop();
if(node->left){
queue_A.push(node->left);
}
if(node->right){
queue_A.push(node->right);
}
}
}
return res;
}
};
思路:bfs 迭代
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
res = []
if not root:
return res
quene= [root]
while quene:
temp = []
for i in range(len(quene)):
node = quene.pop(0)
temp.append(node.val)
if node.left:
quene.append(node.left)
if node.right:
quene.append(node.right)
res.append(temp)
return res
c++实现:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
if(root == NULL){
return res;
}
queue<TreeNode* > queue_A;
queue_A.push(root);
while(!queue_A.empty()){
vector <int> temp;
int count = queue_A.size();
for(int i=0; i<count; i++){
TreeNode* node = queue_A.front();
temp.push_back(node->val);
queue_A.pop();
if(node->left){
queue_A.push(node->left);
}
if(node->right){
queue_A.push(node->right);
}
}
res.push_back(temp);
}
return res;
}
};
思路:利用队列 bfs 层次遍历
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
res = []
if root is None:
return res
quene = [root]
while quene:
temp = []
for i in range(len(quene)):
node = quene.pop(0)
temp.append(node.val)
if node.left:
quene.append(node.left)
if node.right:
quene.append(node.right)
if len(res)%2==0:
res.append(temp)
else:
res.append(temp[::-1])
return res
c++实现:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
if(root == NULL){
return res;
}
queue<TreeNode*> queue_A;
queue_A.push(root);
while(!queue_A.empty()){
vector<int> temp;
int count = queue_A.size();
for(int i=0; i<count; i++){
TreeNode* node = queue_A.front();
temp.push_back(node->val);
queue_A.pop();
if(node->left){
queue_A.push(node->left);
}
if(node->right){
queue_A.push(node->right);
}
}
if(res.size() % 2 == 0){
res.push_back(temp);
}
else{
reverse(temp.begin(), temp.end());
res.push_back(temp);
}
}
return res;
}
};
思路:递归根据 后序遍历 左右根和二叉搜索树特点
class Solution:
def help(self, left, right, postorder):
if left>=right:
return True
m = left
while postorder[m]<postorder[right]:
m += 1 #找到根节点
p = m
while postorder[p]>postorder[right]:
p += 1 #找到大于根节点的值的索引
return p == right and self.help(left, m - 1, postorder) and self.help(m, right-1, postorder)
def verifyPostorder(self, postorder: List[int]) -> bool:
return self.help(0, len(postorder) - 1, postorder)
c++实现:
class Solution {
public:
bool help(int left, int right, vector<int>& postorder){
if(left>=right){
return true;
}
int m = left;
while(postorder[m]<postorder[right]){
m++;
}
int p = m;
while(postorder[p]>postorder[right]){
p++;
}
return (p == right) && help(left, m-1, postorder) && help(m, right-1, postorder);
}
bool verifyPostorder(vector<int>& postorder) {
return help(0, postorder.size() - 1, postorder);
}
};
思路:其实就是深拷贝 ,这里采用dfs。
从头结点 head 开始拷贝;
由于一个结点可能被多个指针指到,因此如果该结点已被拷贝,则不需要重复拷贝;
如果还没拷贝该结点,则创建一个新的结点进行拷贝,并将拷贝过的结点保存在哈希表中;
使用递归拷贝所有的 next 结点,再递归拷贝所有的 random 结点。
python:
"""
# Definition for a Node.
class Node:
def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None):
self.val = int(x)
self.next = next
self.random = random
"""
#其实就是考验深拷贝
class Solution:
def help(self, node, view):#dfs
if node is None:
return node
if node in view:#已经出现过
return view[node]
new_node = Node(node.val, None, None)
view[node] = new_node
new_node.next = self.help(node.next, view)
new_node.random = self.help(node.random, view)
return new_node
def copyRandomList(self, head: 'Node') -> 'Node':
view = {}
return self.help(head, view)
c++:
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
*/
class Solution {
public:
map<Node*, Node*> view;
Node* help(Node* node){
if(node == nullptr){
return nullptr;
}
if(view.count(node)){//已经出现过了的节点 返回就行
return view[node];
}
Node* new_node = new Node(node->val);
view[node] = new_node;//记录已经创建的节点
new_node->next = help(node->next);
new_node->random = help(node->random);
return new_node;
}
Node* copyRandomList(Node* head) {
return help(head);
}
};
思路:中序遍历 设定一个前驱节点pre用来形成双向链接
"""
# Definition for a Node.
class Node:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
"""
class Solution:
def help(self, node):#中序遍历
if node is not None:
self.help(node.left)#递归左子树
if self.pre is not None:
self.pre.right, node.left = node, self.pre #pre和node节点形成双向节点形式
else:
self.head = node #第一次出现 记录head节点
self.pre = node #保存pre节点 并一直不停更新
self.help(node.right)#递归右子树
def treeToDoublyList(self, root: 'Node') -> 'Node':
if root is None:
return
self.pre = None
self.head = None
self.help(root)
self.head.left, self.pre.right = self.pre, self.head
return self.head
c++实现:
/*
// Definition for a Node.
class Node {
public:
int val;
Node* left;
Node* right;
Node() {}
Node(int _val) {
val = _val;
left = NULL;
right = NULL;
}
Node(int _val, Node* _left, Node* _right) {
val = _val;
left = _left;
right = _right;
}
};
*/
class Solution {
public:
Node* pre;
Node* head;
void help(Node* node) {
if(node==NULL){
return;
}
help(node->left);
if(pre != NULL) {
pre->right = node;
node->left = pre;
}
else{
head = node;
}
pre = node;
help(node->right);
}
Node* treeToDoublyList(Node* root) {
if(root == NULL){
return NULL;
}
help(root);
head->left = pre;
pre->right = head;
return head;
}
};
思路:回溯 注意有重复字符串 要剪枝 这里用 view记录 出现过的
python
class Solution:
def backtrace(self, s, view, track):
if len(track) == len(s):
self.res.append(track)
return
for i in range(len(s)):
if view[i]:
continue
if i>0 and s[i]==s[i-1] and view[i-1]==0:
continue
view[i] = 1
store = track
track += s[i]
self.backtrace(s, view, track)
track = store
view[i] = 0
def permutation(self, s: str) -> List[str]:
self.res = []
s = sorted(s)
self.backtrace(s, [0]*len(s), '')
return self.res
c++实现:
class Solution {
public:
vector<string> res;
void backtrace(string s, vector<int> view, string track){
if(s.size() == track.size()){
res.push_back(track);
return;
}
for(int i=0; i<s.size(); i++){
if(view[i]){
continue;
}
if(i>0 && s[i] == s[i-1] && view[i-1] == 0){
continue;
}
view[i] = 1;
string store = track;
track += s[i];
backtrace(s, view, track);
track = store;
view[i] = 0;
}
return;
}
vector<string> permutation(string s) {
vector<int> view(s.size(), 0);
sort(s.begin(), s.end());
backtrace(s, view, "");
return res;
}
};
python代码:
class Solution:
def majorityElement(self, nums: List[int]) -> int:
return sorted(nums)[len(nums)//2]
c++代码:
class Solution {
public:
int majorityElement(vector<int>& nums) {
int length = nums.size();
sort(nums.begin(), nums.end());
return nums[length/2];
}
};
投票法(最优解):
class Solution:
def majorityElement(self, nums: List[int]) -> int:
votes = 0
for num in nums:
if votes == 0:
x = num
if num == x:
votes += 1
else:
votes -= 1
# print('==x:', x)
# print('==votes:', votes)
return x
python:
class Solution:
def quicksort(self, arr):
if len(arr) <= 1:
return arr
privit = arr[len(arr)//2]
middle = [x for x in arr if x == privit]
left = [x for x in arr if x < privit]
right = [x for x in arr if x > privit]
return self.quicksort(left) + middle + self.quicksort(right)
def getLeastNumbers(self, arr: List[int], k: int) -> List[int]:
return self.quicksort(arr)[:k]
c++实现快排:
class Solution {
public:
vector<int> quickSort(vector<int>& arr){
if(arr.size() <= 1){
return arr;
}
int length = arr.size();
int privit = arr[length/2];
vector<int> left;
vector<int> right;
vector<int> middle;
for(int i=0; i<length; i++){
if(privit == arr[i]){
middle.push_back(arr[i]);
}
else if(privit > arr[i]){
left.push_back(arr[i]);
}
else{
right.push_back(arr[i]);
}
}
vector<int> left_sort = quickSort(left);
vector<int> middle_sort = middle;
vector<int> right_sort = quickSort(right);
left_sort.insert(left_sort.end(), middle_sort.begin(), middle_sort.end());
left_sort.insert(left_sort.end(), right_sort.begin(), right_sort.end());
return left_sort;
}
vector<int> getLeastNumbers(vector<int>& arr, int k) {
vector<int> sort_arr = quickSort(arr);
vector<int> res;
for(int i=0; i<k; i++){
res.push_back(sort_arr[i]);
}
return res;
}
};
c++调用现成的排序:
class Solution {
public:
vector<int> getLeastNumbers(vector<int>& arr, int k) {
sort(arr.begin(), arr.end());
vector<int> res;
for(int i=0; i<k; i++){
res.push_back(arr[i]);
}
return res;
}
};
思路:动态规划
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
dp = [0]*len(nums)
dp[0] = nums[0]
for i in range(1, len(nums)):
dp[i] = max(nums[i], dp[i-1]+nums[i])
# print(dp)
return max(dp)
思路:修改数组:
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
if len(nums)==0:
return []
res = nums[0]
for i in range(1,len(nums)):
nums[i] = max(nums[i], nums[i] + nums[i-1])
res = max(nums[i], res)
return res
思路:修改数组2
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
for i in range(1,len(nums)):
nums[i]+=max(nums[i-1],0)
return max(nums)
思路:借助一个变量
o(1),0(n)
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
if len(nums)==0:
return []
value = nums[0]
res = nums[0]
for i in range(1,len(nums)):
value = max(nums[i], value + nums[i])
res = max(value, res)
return res
c++实现
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int length = nums.size();
vector<int> dp(length, 0);
dp[0] = nums[0];
for (int i=1; i<length; i++){
dp[i] = max(nums[i], nums[i] + dp[i-1]);
}
int maxValue = *max_element(dp.begin(), dp.end());
return maxValue;
}
};
思路:
python代码:
class Solution:
def findNthDigit(self, n: int) -> int:
base = 9
digit_nums = 1
while n - base * digit_nums > 0:
n -= base * digit_nums
base *= 10
digit_nums += 1
# print('==n:', n)
# 计算target的值
idx = n % digit_nums # 注意由于上面的计算,n现在表示digits位数的第n个数字
# print('==idx:', idx)
if idx == 0:
idx = digit_nums
number = 1
for i in range(1, digit_nums):
number *= 10
# print('==digit_nums:', digit_nums)
if idx == digit_nums:
number += n // digit_nums - 1
else:
number += n // digit_nums
# print('==number:', number)
return int(str(number)[idx-1])
c++代码:
class Solution {
public:
int findNthDigit(int n) {
long base = 9;
int digit_nums = 1;
while(n - base * digit_nums > 0){
n -= base*digit_nums;
base *=10;
digit_nums++;
}
int index = n % digit_nums;
if(index == 0){
index = digit_nums;
}
long number = 1;
for(int i=1;i<digit_nums;i++){
number *= 10;
}
if(index == digit_nums){
number += n/digit_nums -1;
}
else{
number += n/digit_nums;
}
return int(to_string(number)[index - 1])-'0';
}
};
思路:其实就是排序 这里采用快排 将合并后偏小的字母移动到左边 等于的移动到中间 大于的移动到右边
class Solution:
def minNumber(self, nums: List[int]) -> str:
def fast_sort(arr):
if len(arr) <= 1:
return arr
privot = arr[len(arr)//2]
left = [x for x in arr if x + privot < privot + x]
middle = [x for x in arr if x == privot or x + privot == privot + x]
right = [x for x in arr if x + privot > privot + x]
# print('===left===:', left)
# print('===right===:', right)
# print('====middle:', middle)
return fast_sort(left) + middle + fast_sort(right)
strs = [str(num) for num in nums]
# fast_sort(0, len(strs) - 1)
new_strs = fast_sort(strs)
# print('==new_strs:', new_strs)
return ''.join(new_strs)
c++实现:
class Solution {
public:
vector<string> quickSort(vector<string> strs) {
if(strs.size() <= 1){
return strs;
}
vector<string> left;
vector<string> middle;
vector<string> right;
string privit = strs[int(strs.size()/2)];
for(int i=0; i<strs.size(); i++){
if (strs[i] + privit < privit + strs[i]){
left.push_back(strs[i]);
}
}
for(int i=0; i<strs.size(); i++){
if ((strs[i] == privit) || (strs[i] + privit == privit + strs[i])){
middle.push_back(strs[i]);
}
}
for(int i = 0; i<strs.size(); i++){
if (strs[i] + privit > privit + strs[i]){
right.push_back(strs[i]);
}
}
vector<string> left_sort = quickSort(left);
vector<string> middle_sort = middle;
vector<string> right_sort = quickSort(right);
left_sort.insert(left_sort.end(), middle_sort.begin(), middle_sort.end());
left_sort.insert(left_sort.end(), right_sort.begin(), right_sort.end());
return left_sort;
}
string minNumber(vector<int>& nums) {
vector<string> strs;
for(int i=0; i<nums.size(); i++){
strs.push_back(to_string(nums[i]));
}
vector<string> new_strs= quickSort(strs);
string res;
for(int i=0;i<new_strs.size();i++){
res += new_strs[i];
}
return res;
}
};
思路:动态规划,dp[i] = dp[i-1]+dp[i-2] 满足1~25之间
class Solution:
def translateNum(self, num):
if 0<=num<=9:return 1
nums = [i for i in str(num)]
print(nums)
n = len(nums)
dp = [0]*n
dp[0] = 1
if nums[0] == '1' or (nums[0] == '2' and nums[1] <= '5'):
dp[1] = 2
else:
dp[1] = 1
for i in range(2, n):
if nums[i-1] == '1' or (nums[i-1] == '2' and nums[i] <= '5'):
dp[i] = dp[i-1]+dp[i-2]
else:
dp[i] = dp[i-1]
print(dp)
return dp[-1]
num = 12258
sol = Solution()
sol.translateNum(num)
压缩一下空间,复杂度变为o(n)
class Solution:
def translateNum(self, num):
if 0<=num<=9:return 1
nums = [i for i in str(num)]
print(nums)
n = len(nums)
dp_zero = 1
if nums[0]=='1' or (nums[0]=='2' and nums[1] <= '5'):
dp_one = 2
else:
dp_one = 1
for i in range(2, n):
temp = dp_zero
dp_zero = dp_one
if nums[i-1] == '1' or (nums[i-1] == '2' and nums[i] <= '5'):
dp_one = temp+dp_zero
print(dp_one)
return dp_one
num = 12258
sol = Solution()
sol.translateNum(num)
c++实现:
class Solution {
public:
int translateNum(int num) {
if(0<=num && num<=9){
return 1;
}
string num_string = to_string(num);
int length = num_string.size();
vector<int> dp(length, 0);
dp[0] = 1;
if(num_string[0] == '1' || (num_string[0] == '2' && num_string[1] <= '5')){
dp[1] = 2;
}
else{
dp[1] = 1;
}
for (int i=2; i<length; i++){
if(num_string[i-1] == '1' || (num_string[i-1] == '2' && num_string[i] <= '5')){
dp[i] = dp[i-1] + dp[i-2];
// cout<<"==hahahahahaha=="<<endl;
}
else{
dp[i] = dp[i-1];
}
}
return dp[length-1];
}
};
思路:动态规划:
python代码:
class Solution:
def maxValue(self, grid: List[List[int]]) -> int:
h = len(grid)
w = len(grid[0])
dp = [[0 for _ in range(w)] for _ in range(h)]
# print(np.array(dp))
dp[0][0] = grid[0][0]
for i in range(1, h):
dp[i][0] = dp[i-1][0]+grid[i][0]
# print(np.array(dp))
for i in range(1, w):
dp[0][i] = dp[0][i-1]+grid[0][i]
# print(np.array(dp))
for i in range(1,h):
for j in range(1,w):
dp[i][j] = max(dp[i-1][j],dp[i][j-1])+grid[i][j]
# print(np.array(dp))
return dp[-1][-1]
c++实现:
class Solution {
public:
int maxValue(vector<vector<int>>& grid) {
int h = grid.size();
int w = grid[0].size();
vector<vector<int>> dp(h, vector<int>(w));
dp[0][0] = grid[0][0];
for (int i=1;i<h;i++){
dp[i][0]=dp[i-1][0]+grid[i][0];
}
for (int i=1;i<w;i++){
dp[0][i]=dp[0][i-1]+grid[0][i];
}
for(int i=1;i<h;i++){
for(int j=1;j<w;j++){
dp[i][j]= max(dp[i-1][j],dp[i][j-1])+grid[i][j];
}
}
return dp[h-1][w-1];
}
};
思路:滑动窗口
python代码:
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
left,right =0,0
dict_ = {}
res = 0
while right<len(s):
dict_[s[right]] = dict_.get(s[right], 0) + 1
while dict_[s[right]]>1:
dict_[s[left]]-=1
left+=1
res = max(res, right - left + 1)
right+=1
# print(res)
return res
c++实现:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int left=0;
int right = 0;
int res=0;
map<int,int>dict_;
while(right<s.size()){
dict_[s[right]]++;
while(dict_[s[right]]>1){
dict_[s[left]]--;
left++;
}
res = max(res, right-left+1);
right+=1;
}
return res;
}
};
49-1:丑数
思路:判断是否能整除2,3,5依次整除下去,将不能整除和1进行判断就知道是否是丑数了
class Solution:
def isUgly(self, n: int) -> bool:
if n <= 0: return False
while((n % 2) == 0):
n /= 2
while((n % 3) == 0):
n /= 3
while((n % 5) == 0):
n /= 5
return n == 1
c++循环实现:
class Solution {
public:
bool isUgly(int n) {
if(n <= 0){return false;}
while((n % 2) == 0){
n /= 2;
}
while((n % 3) == 0){
n /= 3;
}
while((n % 5) == 0){
n /= 5;
}
return n == 1;
}
};
c++递归实现:
//递归写法
class Solution {
public:
bool isUgly(int n) {
if(n <= 0){return false;}
while((n % 2) == 0){
return isUgly(n / 2);
}
while((n % 3) == 0){
return isUgly(n / 3);
}
while((n % 5) == 0){
return isUgly(n / 5);
}
return n == 1;
}
};
49-2.丑数
思路:题目要求的这个数字一定是由单个或者多个2,3,5的乘积,如果从小到大去枚举在判断是否由2,3,5乘积组成,工作量会很大,所以考虑用2,3,5从下往上递推,需要开辟空间为n的数组,采用动态规划,2,3,5分别有三个索引,如果满足要求的数字等于2,3,5的倍数乘积,那么就直接将索引加1.
python代码:
class Solution:
def nthUglyNumber(self, n):
dp, index_two, index_three, index_five = [1] * n, 0, 0, 0
for i in range(1, n):
two = dp[index_two] * 2
three = dp[index_three] * 3
five = dp[index_five] * 5
dp[i] = min(two, three, five)
if two==dp[i]:
index_two+=1
if three==dp[i]:
index_three+=1
if five==dp[i]:
index_five+=1
print('==dp:', dp)
return dp[-1]
n = 11
sol = Solution()
sol.nthUglyNumber(n)
c++代码:
class Solution {
public:
int nthUglyNumber(int n) {
vector<int> dp(n,1);
int index_two=0;
int index_three=0;
int index_five=0;
for (int i=1;i<n;i++){
int two = dp[index_two]*2;
int three = dp[index_three]*3;
int five = dp[index_five]*5;
dp[i] = min(min(two, three), five);
if (dp[i]==two){
index_two++;
}
if (dp[i]==three){
index_three++;
}
if (dp[i]==five){
index_five++;
}
}
return dp[n-1];
}
};
50.第一个只出现一次的字符
思路:
最直接的想法是hash,但是hash具有无序性,就改为字符数组计数
python代码:
class Solution:
def firstUniqChar(self, s: str) -> str:
letter_list = [0]*26
for i in s:
letter_list[ord(i) - ord('a')]+=1
# print(letter_list)
for i in s:
if letter_list[ord(i)-ord('a')]==1:
return i
return " "
c++代码:
class Solution {
public:
char firstUniqChar(string s) {
vector<int> letter_list(26, 0);
for(int i=0;i<s.size();i++)
{
letter_list[s[i]-'a']++;
}
vector<int>::iterator iter= letter_list.begin();
for(int i=0;i<s.size();i++)
{
if (iter[s[i]-'a']==1)
{
return s[i];
}
}
return ' ';
}
};
51.数组中的逆序对
思路1:两层for循环 超时
思路2:归并排序 在合并的时候顺便统计逆序对
class Solution:
def mergeSort(self, nums, start, end):
if start >= end:
return
mid = start + (end - start) // 2
self.mergeSort(nums, start, mid)
self.mergeSort(nums, mid + 1, end)
self.merge(nums, start, mid, end)
def merge(self, nums, start, mid, end):
i, j, temp = start, mid + 1, []
while i <= mid and j <= end:
if nums[i] <= nums[j]:
temp.append(nums[i])
i += 1
else:
print('==i:', i)
print('=== start:', start)
print('=== mid:', mid)
print('=== end:', end)
self.cnt += mid - i + 1
temp.append(nums[j])
j += 1
while i <= mid:
temp.append(nums[i])
i += 1
while j <= end:
temp.append(nums[j])
j += 1
for i in range(len(temp)):
nums[start + i] = temp[i]
print('==nums:', nums)
def reversePairs(self, nums):
self.cnt = 0
self.mergeSort(nums, 0, len(nums) - 1)
print('==after nums:', nums)
return self.cnt
nums = [7,5,6,4]
sol = Solution()
sol.reversePairs(nums)
print(sol.cnt)
52.两个链表的第一个公共节点
思路:双指针 两个指针轮流走一遍各自的路程,这样相遇就是公共节点,对于没有公共节点的情况,所以需要判断自身节点不是none,而不是.next是none,在去交换指针,否则会陷入无穷循环,而此时输出就是none。
python
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
first_head = headA
second_head = headB
while first_head !=second_head:
if first_head is not None:
first_head = first_head.next
else:
first_head = headB
if second_head is not None:
second_head = second_head.next
else:
second_head = headA
# print(first_head)
return first_head
c++
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode *first_node;
first_node = headA;
ListNode *second_node;
second_node= headB;
while(first_node != second_node)
{
if(first_node !=NULL)
{
first_node = first_node->next;
}
else
{
first_node = headB;
}
if(second_node !=NULL)
{
second_node = second_node->next;
}
else
{
second_node = headA;
}
}
return first_node;
}
};
思路1:hash
class Solution:
def search(self, nums, target):
dict_={}
for i in range(len(nums)):
dict_[nums[i]] = dict_.get(nums[i],0)+1
print(dict_)
return dict_[target] if target in dict_ else 0
nums = [5,7,7,8,8,10]
target = 8
sol = Solution()
sol.search(nums, target)
思路2:python 双指针
class Solution:
def search(self, nums, target):
left = 0
right = len(nums)-1
while left<right:
middle = left+(right-left)//2
if nums[middle] >=target:
right=middle
else:
left=middle+1
res=0
for i in range(left,len(nums)):
if nums[i]==target:
res+=1
return res
nums = [5,7,7,8,8,10]
target = 8
sol = Solution()
sol.search(nums, target)
思路2:C++ 双指针
#include <map>
#include <vector>
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size()-1;
int res=0;
while (left<right)
{
int middle = left+(right-left)/2;
if (nums[middle]>=target)
{
right=middle;
}
else
{
left=middle+1;
}
}
while (left<nums.size()&&nums[left]==target)
{
left++;
res++;
}
return res;
return 0;
}
};
int main()
{
Solution *p = new Solution();
vector<int> nums;
nums = {5,7,7,8,8,10};
int target = 8;
int res = p->search(nums, target);
cout<<"==res:"<<res<<endl;
delete p;
p=NULL;
return 0;
}
53-2.0~n-1中缺失的数字
思路:双指针,判断中值是否等于索引,等于的话说明缺失值在middle右边,left就变为middle+1,否则在middle左边,right变为middle-1,最后left的值就是缺失值.
python代码
class Solution:
def missingNumber(self, nums: List[int]) -> int:
left = 0
right = len(nums)-1
while left<=right:
middle =left+(right-left)//2
if nums[middle]==middle:#中值等于索引 则说明缺失值在middle右边
left = middle+1
else:#中值不等于索引 则说明缺失值在middle左边
right = middle-1
return left
c++代码:
#include <vector>
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
class Solution {
public:
int missingNumber(vector<int>& nums) {
int left = 0;
int right = nums.size()-1;
while (left<=right)
{
int middle = left+(right-left)/2;
if (nums[middle]==middle)
{
left = middle+1;
}
else
{
right = middle-1;
}
}
return left;
}
};
int main()
{
Solution *p = new Solution();
vector<int> nums;
nums = {0,1,2,3,4,5,6,7,9};
int res = p->missingNumber(nums);
cout<<"==res:"<<res<<endl;
delete p;
p=NULL;
return 0;
}
思路:利用二叉搜索树特点,左子树值<根节点值<右子树值,故采用中序遍历
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def kthLargest(self, root: TreeNode, k: int) -> int:
res = []
def helper(node):
if node is not None:
helper(node.left)
res.append(node.val)
helper(node.right)
helper(root)
print('res:', res)
return res[::-1][k-1]
c++代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> res;
void help(TreeNode* node)
{
if (node !=NULL)
{
help(node->left);
res.push_back(node->val);
help(node->right);
}
}
int kthLargest(TreeNode* root, int k) {
help(root);
return res[res.size()-k];
}
};
55-1.二叉树的深度
递归:python代码
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def maxDepth(self, root):
"""
:type root: TreeNode
:rtype: int
"""
if not root:
return 0
return max(self.maxDepth(root.left),self.maxDepth(root.right))+1
c++代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int maxDepth(TreeNode* root) {
if(root==NULL)
{
return 0;
}
return max(maxDepth(root->left),maxDepth(root->right))+1;
}
};
55-2.平衡二叉树
思路:前序遍历 求当前节点root的深度差,再去遍历求左右子节点的深度差
python代码
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def help(self,node):#计算深度
if node is None:
return 0
return max(self.help(node.left),self.help(node.right))+1
def isBalanced(self, root: TreeNode) -> bool:
if root is None:
return True
return abs(self.help(root.left) - self.help(root.right))<=1 and \
self.isBalanced(root.left) and self.isBalanced(root.right)
c++代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int help(TreeNode* node)
{
if(node == NULL)
{
return 0;
}
return max(help(node->left),help(node->right))+1;
}
bool isBalanced(TreeNode* root) {
if(root == NULL)
{
return true;
}
return abs(help(root->left)-help(root->right))<=1 && isBalanced(root->left)&& isBalanced(root->right);
}
};
56-1.数组中数字出现的次数
思路:hash
python代码:
class Solution:
def singleNumbers(self, nums):
dict_ = {}
for i in range(len(nums)):
dict_[nums[i]] = dict_.get(nums[i],0)+1
print(dict_)
res = []
for key,value in dict_.items():
if value==1:
res.append(key)
print(res)
return res
nums = [4,1,4,6]
sol = Solution()
sol.singleNumbers(nums)
c++代码:
#include <map>
#include <vector>
#include <iostream>
using namespace std;
class Solution {
public:
vector<int> singleNumbers(vector<int>& nums) {
map<int,int>dict_;
for (int k=0;k<nums.size();k++)
{
dict_[nums[k]]++;
}
vector<int> res;
map<int,int>::iterator iter=dict_.begin();
for (;iter!=dict_.end();iter++)
{
if(iter->second==1)
{
res.push_back(iter->first);
}
}
return res;
}
};
int main()
{
vector<int> nums;
nums = {4,1,4,6};
Solution *sol = new Solution();
// vector<int> res;
auto res = sol->singleNumbers(nums);
for (int k=0;k<res.size();k++)
{
cout<<"res[k]"<<res[k]<<endl;
}
delete sol;
sol = NULL;
return 0;
}
56-2.数组中数字出现的次数 II
思路:hash
python代码:
class Solution:
def singleNumber(self, nums: List[int]) -> int:
dict_={}
for num in nums:
dict_[num]=dict_.get(num,0)+1
# print(dict_)
for key,value in dict_.items():
if value==1:
return key
c++代码:
#include <iostream>
#include <vector>
#include <list>
#include <map>
using namespace std;
class Solution {
public:
int singleNumber(vector<int>& nums) {
// cout<<"hhah"<<endl;
map<int,int> dict_;
for (int k=0;k<nums.size();k++)
{
dict_[nums[k]]++;
}
map <int,int>::iterator itor = dict_.begin();
for(;itor!=dict_.end();itor++)
{
// cout<<itor->first<<" "<<itor->second<<endl;
if(itor->second==1){
return itor->first;
}
}
return -1;
}
};
int main()
{
vector<int> nums;
// int nums[] = {3,4,3,3};
nums.push_back(3);
nums.push_back(4);
nums.push_back(3);
nums.push_back(3);
Solution sol;
int res = sol.singleNumber(nums);
cout<<res<<endl;
return 0;
}
思路1:两层for循环 O(n2)
class Solution:
def twoSum(self, nums, target):
res = []
for i in range(len(nums)):
for j in range(i+1, len(nums)):
if nums[i]+nums[j]==target:
res.extend([i, j])
break
print('==res:', res)
return res
nums = [2, 7, 6, 15]
target = 9
sol = Solution()
sol.twoSum(nums, target)
思路2:hash python代码
class Solution:
def twoSum(self, nums, target):
res_dict = {}
for i in range(len(nums)):
value = target - nums[i]
if value in res_dict:
return [res_dict[value], i]
res_dict[nums[i]] = i
print('==res_dict:', res_dict)
return [-1, -1]
nums = [2, 7, 6, 15]
target = 9
sol = Solution()
res = sol.twoSum(nums, target)
print('res:', res)
思路2:c++代码:
#include <string>
#include <iostream>
#include <vector>
#include <list>
#include <map>
#include <typeinfo>
using namespace std;
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map<int, int> dict_;
for(int k=0;k<nums.size();k++)
{
dict_[nums[k]] = k;
}
map <int,int>::iterator iter = dict_.begin();
for (;iter!=dict_.end();iter++)
{
if(dict_[target - iter->first])
{
// cout<<iter->second<<dict_[target - iter->first]<<endl;
return {iter->first,target - iter->first};
}
}
return {-1,-1};
}
};
int main()
{
vector<int> nums;
nums = {2,7,11,15};
int target = 9;
// nums = [2,7,11,15]
Solution sol;
vector<int> res;
res = sol.twoSum(nums,target);
for(int k=0;k<res.size();k++)
{
cout<<"==res[k]:"<<res[k]<<endl;
}
return 0;
}
57-2.和为s的连续正数序列
思路:双指针,和偏大,左指针右移,和偏小,右指针右移,刚好的话就记录相应的值,左指针在右移停止循环即可。
python代码:
class Solution:
def findContinuousSequence(self, target):
list_ = [i for i in range(1, target)]
print('==list_:', list_)
left,right = 0, 0
Sum = 0
res = []
while right<len(list_):
if Sum<target:
Sum+=list_[right]
right+=1
elif Sum == target:
res.append(list_[left:right])
left += 1
Sum -= list_[left-1]
else:
Sum-=list_[left]
left+=1
print('==res:', res)
return res
target = 9
sol = Solution()
sol.findContinuousSequence(target)
c++代码:
#include <map>
#include <vector>
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
class Solution {
public:
vector<vector<int>> findContinuousSequence(int target) {
vector<int> nums;
for (int i=1;i<target;i++)
{
nums.push_back(i);
}
int left=0;
int right=0;
int temp=0;
vector<vector<int>> res;
while (right<nums.size())
{
if(temp<target)
{
temp+=nums[right];
right++;
}
else if(temp>target)
{
temp-=nums[left];
left++;
}
else
{
vector<int> res_temp;
for (int i=left;i<right;i++)
{
res_temp.push_back(nums[i]);
}
res.push_back(res_temp);
temp-=nums[left];
left++;
}
}
return res;
}
};
int main()
{
Solution *p = new Solution();
int target = 9;
vector<vector<int>> res;
res = p->findContinuousSequence(target);
cout<<res.size()<<endl;
for(int k=0;k<res.size();k++)
{
for (int j=0;j<res[k].size();j++)
{
cout<<"res "<<k<<j<<" "<<res[k][j]<<endl;
}
}
delete p;
p = NULL;
return 0;
}
58-1.翻转单词顺序
python代码:
class Solution:
def reverseWords(self, s: str) -> str:
s = s.strip()
# print(s)
s = s.split()
# print(s)
return ' '.join(s[::-1])
c++代码:
#include <map>
#include <vector>
#include <iostream>
#include <queue>
#include <string>
#include <algorithm>
using namespace std;
class Solution {
public:
string reverseWords(string s) {
string res="";
int length = s.size();
// cout<<"==length:"<<length<<endl;
int right = length-1;
while (right>=0)
{
if (s[right]==' ')//去除开头空格
{
right--;
continue;
}
while (right>=0 && s[right]!= ' ')//减少至空格处
{
right--;
}
int index = right;
right++;//加回去到非空格处
if (res.empty())
{
while (s[right]!= ' ' && right<length)
{
res+=s[right];//第一个串 就开始添加
right++;
}
}
else
{
res+=" ";
while (s[right]!= ' ' && right<length)
{
res+=s[right];//第二个串以后 就先添加空格 在继续添加
right++;
}
}
cout<<"res:"<<res<<endl;
right = index;
}
return res;
}
};
int main()
{
Solution *p = new Solution();
// string s = "the sky is blue";
string s = " hello world! ";
string res;
res = p->reverseWords(s);
cout<<"res:"<<res<<endl;
delete p;
p = NULL;
return 0;
}
58-2.左旋转字符串
python代码:
class Solution:
def reverseLeftWords(self, s: str, n: int) -> str:
return s[n:]+s[:n]
c++代码:
class Solution {
public:
string reverseLeftWords(string s, int n) {
string res;
for(int i=n;i<s.size();i++)
{
res+=s[i];
}
for(int i=0;i<n;i++)
{
res+=s[i];
}
return res;
}
};
思路1.超时O(n*k)
class Solution:
def maxSlidingWindow(self, nums, k):
#时间复杂度O(Nk)超时了
res = []
for i in range(len(nums)-k+1):
res.append(max(nums[i:i+k]))
return res
思路1:c++可以:
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> res;
if (nums.size()==0)
{
return res;
}
for (int i=0;i<nums.size()-k+1;i++)
{
int temp = INT_MIN;
for (int j=i;j<i+k;j++)
{
temp = max(temp, nums[j]);
}
res.push_back(temp);
}
return res;
}
};
思路2:
动态规划:时间复杂度O(N)
1.将数组分成k+1个,剩下的一个可能不足;
2.left数组存储每个拆分的从左到右的值,对于left来说每个块最右边元素最大;
3.right数组存储每个拆分的从右到左的值,对于right来说每个块最左边元素最大;
4.最后在利用left和right求最大值,max(left[i],right(j)) i每个块最右边元素索引,j每个块最左边元素索引
class Solution:
def maxSlidingWindow(self, nums, k):
n = len(nums)
if n * k == 0:
return []
if k == 1:
return nums
left = [0] * n
left[0] = nums[0]
right = [0] * n
right[n - 1] = nums[n - 1]
for i in range(1, n):
#从左往右
if i%k==0:#分块的第一个元素
left[i] = nums[i]
else:
left[i] = max(left[i-1],nums[i])
# 从右往左
j = n-i-1
# 分块的最右边元素
if (j+1) % k == 0:
right[j] = nums[j]
else:
right[j] = max(right[j + 1], nums[j])
print('===left:', left)
print('===right:', right)
#最后在利用left和right求最大值
output = []
for i in range(n - k + 1):
output.append(max(left[i + k - 1], right[i]))
return output
nums = [1,3,-1,-3,5,3,6,7]
k = 3
sol = Solution()
res = sol.maxSlidingWindow(nums, k)
print('res:', res)
思路3:双端队列:用一个队列一直存储更新最大值
# 双端队列:用一个队列一直存储更新最大值
class Solution:
def maxSlidingWindow(self, nums, k):
length = len(nums)
if length == 0:
return []
res = []
quene = []
for j in range(length):
i = j-k+1
if i > 0 and quene[0] == nums[i-1]:#当要左移掉的元素等于quene头部元素,那么quene就移除头部元素
quene.pop(0)
while quene and quene[-1] < nums[j]:#保持quene里面都是单调递减的,且头部元素最大
quene.pop()
quene.append(nums[j])
print('==quene:', quene)
if i >= 0:
res.append(quene[0])
return res
nums = [1, 3, -1, -3, 5, 3, 6, 7]
k = 3
sol = Solution()
res = sol.maxSlidingWindow(nums, k)
print(res)
思路3:c++代码
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> res;
vector<int> quene;
for (int j=0;j<nums.size();j++)
{
int i = j-k+1;
if(i>0 && nums[i-1]==quene.front())//顶部元素正好等于了要左移元素 那么将队列顶部元素移动开
{
quene.erase(quene.begin());
}
while (!quene.empty() && quene.back()<nums[j])//保持单调递减
{
quene.erase(quene.end()-1);
}
quene.push_back(nums[j]);
// cout<<"quene.front():"<<quene.front()<<endl;
// cout<<"quene.back():"<<quene.back()<<endl;
if(i>=0)
{
res.push_back(quene.front());
}
}
return res;
}
};
59-2.队列的最大值
思路1: 其中去Max操作是o(n)
class MaxQueue:
def __init__(self):
self.quene = []
def max_value(self):
if len(self.quene):
return max(self.quene)
else:
return -1
def push_back(self, value):
self.quene.append(value)
def pop_front(self):
if len(self.quene):
return self.quene.pop(0)
else:
return -1
# Your MaxQueue object will be instantiated and called as such:
obj = MaxQueue()
param_1 = obj.max_value()
value = 10
obj.push_back(value)
param_3 = obj.pop_front()
print(param_3)
思路2:采用双端队列,优化取max操作
class MaxQueue:
def __init__(self):
self.queue = []
self.deque = []
def max_value(self):
return self.deque[0] if self.deque else -1
def push_back(self, value):
self.queue.append(value)
while self.deque and self.deque[-1] < value:
self.deque.pop()
self.deque.append(value)
def pop_front(self):
if len(self.queue) == 0:return -1
val = self.queue.pop(0)
if val == self.deque[0]:
self.deque.pop(0)
return val
obj = MaxQueue()
param_1 = obj.max_value()
for value in [10, 5, 8]:
obj.push_back(value)
print('==obj.queue:', obj.queue)
print('==obj.deque:', obj.deque)
param_3 = obj.pop_front()
print('==param_3:', param_3)
print('==obj.queue:', obj.queue)
print('==obj.deque:', obj.deque)
60.n个骰子的点数
思路:一个骰子的概率 first_prob = [1/6, 1/6, 1/6, 1/6, 1/6, 1/6]
两个骰子的概率 temp_prob = [5*2+1]
temp_prob[i+x] = first_prob[i]*second_prob[x]
第n个骰子的概率 temp_prob = [5*n+1]*0
#一个骰子的概率 first_prob = [1/6, 1/6, 1/6, 1/6, 1/6, 1/6]
#两个骰子的概率 temp_prob = [5*2+1]
# temp_prob[i+x] = first_prob[i]*second_prob[x]
#第n个骰子的概率 temp_prob = [5*n+1]*0
class Solution:
def dicesProbability(self, n):
first_prob, second_prob = [1/6]*6, [1/6]*6
for index in range(2, n+1):
temp_prob = [0]*(5*index+1)
for i in range(len(first_prob)): #第一个骰子的概率
for j in range(len(second_prob)): #第二个骰子的概率
temp_prob[i+j] += first_prob[i]*second_prob[j]
print('==temp_prob:', temp_prob)
#第一个骰子的概率换成前几次计算的概率也就是n-1
first_prob = temp_prob
print('==first_prob:', first_prob)
return first_prob
n = 2
sol = Solution()
sol.dicesProbability(n)
c++代码:
class Solution {
public:
vector<double> dicesProbability(int n) {
vector<double> probs;
vector<double> first_prob;
for (int i=0;i<6;i++)
{
probs.push_back(1./6);
first_prob.push_back(1./6);
}
for (int i=2;i<n+1;i++)
{
vector<double> temp_prob;
for (int temp_i=0;temp_i<5*i+1;temp_i++)
{
temp_prob.push_back(0);
}
for (int j=0;j<probs.size();j++)
{
for (int k=0;k<first_prob.size();k++)
{
temp_prob[j+k]+=probs[j]*first_prob[k];
}
}
probs = temp_prob;
}
return probs;
}
};
61.扑克牌中的顺子
思路:1.除去0发现重复的就返回false
2. 如果没有重复,则再判断除去的0的最大最小值差值与5的关系
python代码:
#思路:1.除去0发现重复的就返回false
#2. 如果没有重复,则再判断除去的0的最大最小值差值与5的关系
class Solution:
def isStraight(self, nums):
nums = sorted(nums)
index = 0
for i in range(len(nums)-1):
if nums[i]==0:
index+=1
elif nums[i] == nums[i+1]:#先去重
return False
if nums[-1]-nums[index]>4:
return False
return True
# nums = [0,0,1,2,5]
nums = [0,6,1,2,5]
sol = Solution()
res = sol.isStraight(nums)
print(res)
c++代码:
class Solution {
public:
bool isStraight(vector<int>& nums) {
int index = 0;
sort(nums.begin(),nums.end());
for(int i=0;i<nums.size();i++)
{
if (nums[i]==0)
{
index+=1;
}
else if(i>0 && nums[i]==nums[i-1])
{
return false;
}
}
if(nums.back() - nums[index]>4)
{
return false;
}
return true;
}
};
62.圆圈中最后剩下的数字
思路:一直迭代
python代码:
#思路:一直迭代
class Solution:
def lastRemaining(self, n, m):
index = 0
num_list = [i for i in range(n)]
while len(num_list) > 1:
print('==num_list:', num_list)
index = (index + m-1) % len(num_list)
print('==index:', index)
num_list.pop(index)
return num_list[0]
n = 4
m = 3
sol = Solution()
sol.lastRemaining(n, m)
c++代码:
上述代码改写成c++会超时,故换一种思路,从两个人一直往上递推到n个人
class Solution {
public:
int lastRemaining(int n, int m) {
int pos=0;
for (int i=2;i<=n;i++)
{
pos = (pos+m)%i;
}
return pos;
}
};
63.股票的最大利润
思路:一次遍历更新最小价格和利润即可 python代码
class Solution:
def maxProfit(self, prices: List[int]) -> int:
if len(prices)==0:
return 0
min_price = prices[0]
max_profit = 0
for i in range(1,len(prices)):
max_profit = max(max_profit, prices[i] - min_price)
min_price = min(min_price, prices[i])
# print(max_profit)
return max_profit
dp:
class Solution:
def maxProfit(self, prices: List[int]) -> int:
if len(prices)==0:
return 0
dp =[0]*len(prices)
min_price = prices[0]
for i in range(1,len(prices)):
dp[i] = max(dp[i-1],prices[i]-min_price)
min_price = min(min_price,prices[i])
# print(dp)
return dp[-1]
c++代码:
class Solution {
public:
int maxProfit(vector<int>& prices) {
if(prices.size()==0){return 0;}
int min_price = prices[0];
int profit = 0;
for(int i=1;i<prices.size();i++){
profit = max(profit, prices[i]-min_price);
min_price = min(min_price, prices[i]);
}
return profit;
}
};
64.求1+2+…+n
python:
class Solution:
def sumNums(self, n: int) -> int:
return n if n==0 else n+self.sumNums(n-1)
c++:
class Solution {
public:
int sumNums(int n) {
if (n==1){return n;}
return n+sumNums(n-1);
}
};
65.不用加减乘除做加法
思路:既然不能用四则运算,那么就用位运算替代
class Solution {
public:
int add(int a, int b) {
if(a==0 || b==0){
return a==0?b:a;
}
int sum_=0;
int carry=0;
while (b!=0)
{
sum_ = a^b;
carry = (unsigned int) (a&b)<<1;
a = sum_;
b = carry;
}
return a;
}
};
66.构建乘积数组
思路1:双指针:
超时
# 双层for循环 超时 o(n^2)
class Solution:
def constructArr(self, a):
n = len(a)
res = [0]*n
index = 0
while index<n:
temp = 1
left = index-1
right = index+1
while left>=0:
temp*=a[left]
left-=1
while right<n:
temp *= a[right]
right += 1
res[index]= temp
index+=1
print(res)
return res
思路2:dp 用left记录存储i的左半部分乘积
用right记录存储i的右半部分乘积
再用left和right对应位置的数相乘就是结果
#B[i] = A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n]
#dp left存储i的左半部分乘积
#dp right存储i的左半部分乘积
class Solution:
def constructArr(self, a):
n = len(a)
left, right = [1] * n, [1] * n
for i in range(1, n):
left[i] = left[i - 1] * a[i - 1]
print(left)
for i in range(n-2, -1, -1):
right[i] = right[i+1]*a[i+1]
print(right)
res = [0]*len(a)
for i in range(n):
res[i] = left[i]*right[i]
print(res)
return res
a = [1,2,3,4,5]
sol = Solution()
sol.constructArr(a)
思路3:优化上一个dp
#优化版
class Solution:
def constructArr(self, a):
n = len(a)
left, right = [1] * n, [1] * n
for i in range(1, n):
left[i] = left[i - 1] * a[i - 1]
print(left)
temp = 1
for i in range(n-2, -1, -1):
temp = temp*a[i+1]
left[i] *= temp
print(left)
return left
a = [1,2,3,4,5]
sol = Solution()
sol.constructArr(a)
c++:
class Solution {
public:
vector<int> constructArr(vector<int>& a) {
int n = a.size();
vector<int>res(n,1);
for (int i=1;i<n;i++){
res[i] = res[i-1]*a[i-1];
}
int temp=1;
for (int i=n-2;i>-1;i--){
temp *= a[i+1];
res[i] *= temp;
}
return res;
}
};
67.把字符串转换成整数
思路:
1.去除首尾空格
2.判断符号索引
3.从符号索引的下一位进行转换 遇到字母就停止
#思路:
# 1.去除首尾空格
# 2.判断符号索引
# 3.从符号索引的下一位进行转换 遇到字母就停止
class Solution:
def strToInt(self, str):
new_str = str.strip()
if len(new_str)==0:
return 0
start = 0
sign = 1
if new_str[0]=='-':
start=1
sign = -1
if new_str[0]=='+':
start=1
sign = 1
res = 0
for i in range(start,len(new_str)):
if "0"<=new_str[i]<="9":
res = 10*res + int(new_str[i])
else:
break
print(res)
res = sign*res
if res >= 2 ** 31 - 1:
return 2**31-1
if res<=-2**31:
return -2**31
return res
str = " -42ddff"
sol = Solution()
sol.strToInt(str)
c++:
class Solution {
public:
int strToInt(string str) {
int index =0;
for (int i=0;i<str.size();i++){
if (str[i]==' '){
index++;
}
else{
break;
}
}
string new_str = "";
new_str = str.substr(index);
// cout<<new_str<<endl;
int start=0;
int sign=1;
long res=0;
if (new_str[0]=='-'){
sign=-1;
start=1;
}
if (new_str[0]=='+'){
sign=1;
start=1;
}
for(int i=start;i<new_str.size();i++){
if('0'<=new_str[i] && new_str[i]<='9'){
res=10*res+(new_str[i]-'0');
if(sign==1 && res>INT_MAX){
return INT_MAX;
}
if(sign==-1 && res-1>INT_MAX){
return INT_MIN;
}
}
else{
break;
}
}
res = sign*res;
if (res>pow(2,31)-1){
return pow(2,31)-1;
}
if (res<-pow(2,31)){
return -pow(2,31);
}
return res;
}
};
68-1.二叉搜索树的最近公共祖先
思路:
1.从根节点开始遍历树
2.如果节点 p 和节点 q 都在右子树上,那么以右孩子为根节点继续 1 的操作
3.如果节点 p 和节点 q 都在左子树上,那么以左孩子为根节点继续 1 的操作
4.如果条件 2 和条件 3 都不成立,这就意味着我们已经找到p 和q 的公共祖先了
解法1:当成普通二叉树
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if root==p or root==q or root is None:
return root
left_node = self.lowestCommonAncestor(root.left,p,q)
right_node = self.lowestCommonAncestor(root.right,p,q)
if left_node is None:
return right_node
if right_node is None:
return left_node
return root
解法2利用二叉搜索树特点根节点值和左右子树值大小的特点.递归法
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
#利用二叉搜索树的特点
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
print('==root.val:', root.val)
if root.val< min(p.val, q.val):#都大于根节点的值 将右孩子作为根节点
return self.lowestCommonAncestor(root.right, p, q)
elif root.val > max(p.val, q.val):#都小于根节点的值 将左孩子作为根节点
return self.lowestCommonAncestor(root.left, p, q)
else:#找到公共祖先
return root
解法3.迭代法
#利用二叉搜索树的特点
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
node = root
while node:
if node.val < min(p.val,q.val):
node = node.right
elif node.val > max(p.val,q.val):
node = node.left
else:
return node
c++:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root->val<min(p->val,q->val)){
return lowestCommonAncestor(root->right,p,q);
}
if(root->val>max(p->val,q->val)){
return lowestCommonAncestor(root->left,p,q);
}
return root;
}
};
python:递归
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if root is None or root==p or root==q:#递归终止条件 节点为空 或者节点等于p,q其中之一
return root
left = self.lowestCommonAncestor(root.left, p, q)#遍历左子树
right = self.lowestCommonAncestor(root.right, p, q)#遍历右子树
if left is None:#左子树为空 就去右子树
return right
if right is None:#右子树为空 就去左子树
return left
return root#左右子树都不为空 说明找到了节点
c++:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if (root == NULL){
return NULL;
}
if(root->val == p->val || root->val == q->val){
return root;
}
TreeNode* left_node = lowestCommonAncestor(root->left,p,q);
TreeNode* right_node = lowestCommonAncestor(root->right,p,q);
if(left_node !=NULL && right_node!=NULL){
return root;
}
if (left_node==NULL){
return right_node;
}
return left_node;
}
};