Day1
1、用两个栈实现队列
输入:
[“CQueue”,“appendTail”,“deleteHead”,“deleteHead”] 这一行表示每一行代码的操作
[[],[3],[],[]] 这个表示每一行代码操作所需要的参数
举例:
CQueue 表示新建一个CQueue对象,对应的所需参数为[],即此操作不需要参数。
appendTail 表示执行一个appendTail()操作,对应要被操作的元素为3。
deleteHead表示执行一个deleteHead()操作,对应的所需参数为[],即此操作不需要参数。 deleteHead
表示执行一个deleteHead操作,对应的所需参数为[],即此操作不需要参数。以上的输入其实是一个代码执行的步骤描述与其对应所需参数。
class CQueue:
def __init__(self):
self.stack1 = []
self.stack2 = []
def appendTail(self, value: int) -> None:
self.stack1.append(value)
def deleteHead(self) -> int:
if self.stack2 == []:
if self.stack1 == []:
return -1
while self.stack1:
self.stack2.append(self.stack1.pop())
return self.stack2.pop()
2、包含min函数的栈
class MinStack:
'''初始化两个个栈'''
def __init__(self):
self.stack=[]
self.minStack=[]
def push(self,x):
self.stack.append(x)
'''如果minStack为空或者
新加入的x比minStack中最
后一个数小,
把x加入到minStack中'''
if not self.minStack or x<=self.minStack[-1]:
self.minStack.append(x)
def pop(self):
'''如果要删除的最后一个数是最小的数,把minStack中的数删掉'''
if self.stack[-1]==self.minStack[-1]:
self.minStack.pop()
self.stack.pop()
def top(self):
return self.stack[-1]
def min(self):
return self.minStack[-1]
Day2
1、从尾到头打印链表
class Solution:
def reversePrint(self, head: ListNode) :
reslist=[]
while head:
reslist.append(head.val)
head=head.next
return reslist[::-1]
2、反转链表
class Solution:
def reverseList(self,head:ListNode):
reslist=[]
while head:
reslist.append(head.val)
head=head.next
reslist=reslist[::-1]
node=ListNode(0)
p=node
for i in reslist:
p.next=ListNode(i)
p=p.next
return node.next
Day3
1、替换空格
class Solution:
def replaceSpace(self, s: str) -> str:
str=s.replace(' ','%20')
return str
2、左旋转字符串
方法一:
class Solution:
def reverseLeftWords(self, s: str, n: int) -> str:
length=len(s)
res_str=''
for i in range(length):
res_str+=s[(n+length)%length]
n+=1
return res_str
方法二:
class Solution:
def reverseLeftWords(self, s: str, n: int) -> str:
return s[n:]+s[:n]
Day4
1、数组中重复的数字
先排序,然后看相邻元素是否有相同的,有直接return。 不过很慢,时间O(nlogn)了,空间O(1)
class Solution:
def findRepeatNumber(self, nums: List[int]) -> int:
nums.sort()
pre=nums[0]
n=len(nums)
for i in range(1,n):
if pre == nums[i]:
return pre
else:
pre = nums[i]
2、在排序数组中查找数字
直白方法一:
class Solution:
def search(self, nums: List[int], target: int) -> int:
count=0
for i in nums:
if i==target:
count+=1
return count
内存占用太多,因为排序过所以数组无须全部遍历一遍
3、0~n-1中缺失的数字
class Solution:
def missingNumber(self, nums: List[int]) -> int:
pre=nums[0]
n=len(nums)
for i in range(1,n):
if nums[i]!= pre + 1:
return pre+1
pre=nums[i]
if nums[0]!=0:
return 0
else:
return nums[n-1]+1
Day5
1、二维数组中的查找
方法一:
思路:二维数组变成一维并且排序,之后按序查找
class Solution:
def findNumberIn2DArray(self, matrix: List[List[int]], target: int):
List_res=sum(matrix,[])
List_res.sort()
n=len(List_res)
if List_res:
for num in range(n):
if List_res[num]==target:
return True
break
if List_res[num] > target:
break
return False
return False
else:
return False
改进:
class Solution:
def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool:
i, j = len(matrix) - 1, 0
while i >= 0 and j < len(matrix[0]):
if matrix[i][j] > target: i -= 1
elif matrix[i][j] < target: j += 1
else: return True
return False
2、旋转数组的中最小数字
方法一:
class Solution:
def minArray(self, numbers: List[int]) -> int:
pre=numbers[0]
for num in numbers:
if pre > num:
return num
break
pre = num
return numbers[0]
改进方法(二分查找法):
class Solution:
def minArray(self, numbers: List[int]) -> int:
i,j=0,len(numbers)-1
while(i<j):
m=(i+j)//2
if numbers[m] > numbers[j]: i=m+1
elif numbers[m] < numbers[j]: j=m-1
else:j-=1
return numbers[i]
3、第一个只出现一次的字符
字符串可以直接调用count()函数查找字符出现的次数
class Solution:
def firstUniqChar(self, s: str) -> str:
for str in s:
if s.count(str)==1:
return str
break
return ' '
Day6 二叉树=====薄弱部分,多看!!
1、从上到下打印二叉树
class Solution:
def levelOrder(self, root: TreeNode) -> List[int]:
if not root: return []
self.res_list=[]
queue=[root] // 先把根节点放入队列
while queue: //循环队列
size=len(queue) // 查看这一层共有多少个节点
for i in range(size):
cur=queue.pop(0)
self.res_list.append(cur.val)
if cur.left:
queue.append(cur.left)
// 如果左节点不为空,给这一层添加节点,
// 之后在下一次遍历时把val值返回给res_list
if cur.right:
queue.append(cur.right)
// 如果右节点不为空,给这一层添加节点,
// 之后在下一次遍历时把val值返回给res_list
return self.res_list
2、从上到下打印二叉树
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
if not root: return []
res_list=[]
queue=[root]
while queue:
tmp=[]
for i in range(len(queue)):
cur=queue.pop(0)
tmp.append(cur.val)
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
res_list.append(tmp)
return res_list
3、从上到下打印二叉树
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
if not root: return []
queue=[root]
res_list=[]
i=1
while queue:
tmp=[]
for num in range(len(queue)):
cur=queue.pop(0)
tmp.append(cur.val)
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
res_list.append(tmp)
for i in range(len(res_list)):
if i%2==1:
res_list[i]=res_list[i][::-1]
return res_list
Day7 搜索与回溯算法 ======薄弱部分,多看
1、树的子结构
若树 BB 是树 AA 的子结构,则子结构的根节点可能为树 AA 的任意一个节点。因此,判断树 BB 是否是树 AA的子结构,需完成以下两步工作:
- 先序遍历树 AA 中的每个节点 (对应函数 isSubStructure(A, B))
- 判断树 A中 以 N(A)为根节点的子树是否包含树 B 。(对应函数 recur(A, B))
算法流程:
recur(A, B) 函数:
终止条件:
1)当根节点 BB 为空:说明树 BB 已匹配完成(越过叶子节点),因此返回 true;
2)当根节点 AA 为空:说明已经越过树 AA 叶子节点,即匹配失败,返回 false;
3)当节点 AA 和 BB 的值不同:说明匹配失败,返回 false;返回值:
1)判断 AA 和 BB 的左子节点是否相等,即 recur(A.left, B.left) ;
2)判断 AA 和 BB的右子节点是否相等,即 recur(A.right, B.right) ;
isSubStructure(A, B) 函数:
特例处理:
当 树 AA 为空 或 树 BB 为空 时,直接返回 false;返回值: 若树 BB 是树 AA 的子结构,则必满足以下三种情况之一,因此用或 || 连接;
1)以 节点 AA 为根节点的子树包含树 BB,对应 recur(A, B);
2)树 BB 是 树 AA 左子树 的子结构,对应isSubStructure(A.left, B);
3)树BB 是 树 AA 右子树 的子结构,对应 isSubStructure(A.right, B);
class Solution:
def isSubStructure(self, A: TreeNode, B: TreeNode) -> bool:
def recur(A:TreeNode,B:TreeNode):
if not B:
return True
if not A or A.val!=B.val:
return False
return recur(A.left,B.left) and recur(A.right,B.right)
return bool(A and B) and (recur(A, B) or self.isSubStructure(A.left, B) or self.isSubStructure(A.right, B))
2、二叉树的镜像
class Solution:
def mirrorTree(self, root: TreeNode) -> TreeNode:
if not root: return
root.left, root.right = self.mirrorTree(root.right), self.mirrorTree(root.left)
return root
3、对称的二叉树
class Solution:
def isSymmetric(self, root: TreeNode) -> bool:
def recur(L,R):
if not L and not R: return True
if not L or not R or L.val!=R.val:
return False
return recur(L.left,R.right) and recur(L.right,R.left)
return recur(root.left,root.right) if root else True
Day8
1、斐波那契数列
class Solution:
def fib(self, n) :
a, b = 0, 1
for _ in range(n):
a, b = b, a + b
return a % 1000000007
2、最小花费爬楼梯
3、青蛙跳台阶
Day9
1、不同路径得数目
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param matrix int整型二维数组 the matrix
# @return int整型
#
class Solution:
def minPathSum(self , matrix: List[List[int]]) -> int:
# write code here
k=0
m=len(matrix)
n=len(matrix[0])
cost=[[0] * n for i in range(m)]
cost[0][0]=matrix[0][0]
# print(m,n,cost,matrix)
# print(m)
for j in range(1,n):
cost[0][j]=cost[0][j-1]+matrix[0][j]
for i in range(1,m):
cost[i][0]=cost[i-1][0]+matrix[i][0]
for i in range(1,m):
# print(i)
for j in range(1,n):
# print(i,j,matrix[i][j-1],matrix[i-1][j],matrix[0][1])
if cost[i][j-1]<cost[i-1][j]:
cost[i][j]=cost[i][j-1]+matrix[i][j]
else:
cost[i][j]=cost[i-1][j]+matrix[i][j]
k=cost[i][j]
print(j,k)
return k
2、矩阵的最小路径之和
Day 10
1、兑换零钱
2、最长上升子序列
Day 11
1、连续子数组的最大和
Day12
1、盛最多水的容器
思路:
1、暴力破解:
V=(左右距离之差)* min(height1,height2)
2、左右向中心移动,虽然宽度变小,但是可能高度变大,然后依次进行比较
class Solution(object):
def maxArea(self, height):
"""
:type height: List[int]
:rtype: int
"""
res = 0
wait_str = 0
left = 0
right = len(height)-1
res = (right-left)*min(height[0],height[-1])
while left < right:
if height[left] <= height[right]:
left += 1
else:
right -= 1
wait_str = (right-left)*min(height[left],height[right])
if wait_str > res:
res = wait_str
return res
2、三数之和
超出内存限制
class Solution(object):
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
nums.sort()
res = []
if nums[-1] < 0:
return []
if nums[0] > 0:
return []
for i in range(len(nums)):
left = i + 1
right = len(nums) -1
while left < right:
if nums[i] + nums[left] + nums[right] > 0:
right -=1
elif nums[i] + nums[left] + nums[right] < 0:
left +=1
else:
res.append([nums[i], nums[left], nums[right]])
left +=1
return list(set([tuple(t) for t in res]))# 去重,有[0,0,0,0]的情况
Day 13
1、搜索插入位置
class Solution(object):
def searchInsert(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
if target < nums[0]:
return 0
if target > nums[-1]:
return len(nums)
for index in range(len(nums)):
if target <= nums[index]:
return index
else:
pass
2、外观数列
class Solution(object):
def countAndSay(self, n):
"""
:type n: int
:rtype: str
"""
dic = {1: '1'}
for i in range(n + 1):
if i >1:
wait_str = dic[i-1]
# print(wait_str)
res = self.cal_str(wait_str)
# print(res)
dic [i] = res
return dic[n]
def cal_str(self, wait_str):
count = 1
res = ''
if len(wait_str) == 1:
return '1' + wait_str
for index in range(len(wait_str)):
if index + 1 < len(wait_str):
if wait_str[index + 1] == wait_str[index]:
count += 1
if index + 1 == len(wait_str) - 1:
res += str(count)
res += wait_str[index]
else:
res += str(count)
res += wait_str[index]
count = 1
if index + 1 == len(wait_str) - 1:
res += str(count)
res += wait_str[index + 1]
return res
Day14
1、最长公共子串
class Solution(object):
def longestCommonPrefix(self, strs):
"""
:type strs: List[str]
:rtype: str
"""
res_str = strs[0]
wait_len = 0
for s in strs:
wait_str = ''
for index in range(len(res_str)):
# print(index, len(s), len(res_str))
if index < len(s) and index < len(res_str):
if s[index] == res_str[index]:
wait_str += s[index]
else:
res_str = wait_str
else:
res_str = wait_str
print(wait_str, res_str)
return res_str
2、三数之和
class Solution(object):
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
nums.sort()
res_list = []
print(nums)
if nums[-1] <= 0 or nums[0] >= 0:
if nums[0:3] == [0, 0, 0] or nums[-3:] == [0,0,0]:
return [[0,0,0]]
else:
return []
else:
for index in range(1, len(nums)):
i = 0
j = len(nums) -1
while i < j:
if i == index:
break
if j == index:
break
if nums[index] + nums [i] + nums[j] > 0:
j -= 1
elif nums[index] + nums [i] + nums[j] < 0:
i += 1
else:
wait_list = [nums[index], nums[i],nums[j]]
wait_list.sort()
if wait_list not in res_list:
res_list.append(wait_list)
j -= 1
return res_list
3、最接近的三数之和
class Solution(object):
def threeSumClosest(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
nums.sort()
# print(nums)
wait_target = 100000
res_target = 0
for index in range(1, len(nums)):
i = 0
j = len(nums) - 1
while i < j:
if nums[index] + nums[i] + nums[j] < target:
if abs(nums[index] + nums[i] + nums[j]-target) < wait_target and \
i != index and j != index and i != j:
wait_target = abs(nums[index] + nums[i] + nums[j]-target)
res_target = nums[index] + nums[i] + nums[j]
i += 1
elif nums[index] + nums[i] + nums[j] > target:
if abs(nums[index] + nums[i] + nums[j]-target) < wait_target and \
i != index and j != index and i != j:
wait_target = abs(nums[index] + nums[i] + nums[j]-target)
res_target = nums[index] + nums[i] + nums[j]
j -= 1
else:
if i == index:
break
elif j == index:
break
else:
return target
return res_target
Day 15
1、电话号码的字母之和
import queue
class Solution:
def letterCombinations(self, digits: str) -> List[str]:
q_list = []
search_list = ['abc','def','ghi','jkl','mno','pqrs','tuv','wxyz']
q = queue.Queue()
res = ''
if digits == "":
return []
for i in range(len(search_list[int(digits[0])-2])):
q.put(search_list[int(digits[0])-2][i])
len_item = 0
p = 0
while len(q.queue[0]) != len(digits):
item = q.get()
if len_item < len(item):
p += 1
for i in digits[p:p+1]:
index = int(i) - 2
print(item, search_list[index])
for j in range(len(search_list[index])):
res = item + search_list[index][j]
if len(res) > len(digits):
break
q.put(res)
len_item = len(item)
# print(p, item)
while not q.empty():
item = q.get()
q_list.append(item)
return q_list
2、单词替换
#include <string>
class Solution {
public:
string replaceWords(vector<string>& dictionary, string sentence) {
string wait_str;
string res_str;
string string_sentense;
bool flag = false;
sentence += ' ';
for(int i =0; i<=sentence.size();i++){
// 单词拆分
if (!isspace(sentence[i])){
wait_str += sentence[i];
}
else{
// 判断是否为新的wait_str
bool wait_str_flag = true;
// sentence每识别一个单词进行词根匹配
for(int i=0; i<dictionary.size(); i++){
for (int j=0;j<wait_str.size();j++){
if (dictionary[i][j] != wait_str[j]){
if (wait_str_flag){
flag = true;
}
break;
}
if (dictionary[i][j] == wait_str[j] && j==dictionary[i].size()-1){
// 第一个符合wait_str的dictionary的单词
if(wait_str_flag){
res_str = dictionary[i];
wait_str_flag = false;
}
if(wait_str_flag == false && res_str.size()>dictionary[i].size()){
res_str = dictionary[i];
}
flag = false;
}
}
// cout<<wait_str_flag<<dictionary[i]<<i<<j<<res_str<<endl;
if(i == dictionary.size()-1 && wait_str_flag == false){
string_sentense += res_str;
if(res_str != ""){
string_sentense += ' ';
}
res_str.clear();
}
}
if (flag){
string_sentense += wait_str;
string_sentense += ' ';}
wait_str.clear();
}
}
return string_sentense.substr(0,string_sentense.length() - 1);
}
};
3、缺失的第一个正数
思路:新建与nums等长的向量num_sort,对应索引上放入nums的数值,查找向量num_sort上值为0的数值
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
int k=1;
bool flag = false;
vector<int> num_sort = vector<int>(nums.size());
for(int i=0;i<nums.size();i++){
if(nums[i]>nums.size()){
num_sort.push_back(nums[i]);
}
if (nums[i] > 0 && nums[i]<=nums.size()){
int k = nums[i];
num_sort[k-1] = nums[i];
}
}
for(int i=0;i<num_sort.size();i++){
if (num_sort[i] == 0){
return i+1;
}
}
return num_sort.size()+1;
}
};
Day 16
1、最长有效括号
#include <stack>
class Solution {
public:
int longestValidParentheses(string s) {
stack<int> test;
int count=0;
int res=0;
int val=0;
bool flag = true;
test.push(-1);
if (s == ""){
return 0;
}
for(int i=0;i<s.length();i++){
if(s[i] == '(' ){
test.push(i);
}
if(s[i] == ')'){
test.pop();
if(test.empty()){
test.push(i);
}
else{
if(val < i - test.top()) {
val = i - test.top();
}
}
}
}
return val;
}
};
2、买卖股票的有效时机
class Solution {
public:
int maxProfit(vector<int>& prices) {
int res = 0;
int out;
vector<int> daily_profit = vector<int> (prices.size());
if(prices.size()==2){
if (prices[1]-prices[0]>0){
return prices[1]-prices[0];
}
else{
return 0;
}
}
for(int i=1; i<prices.size(); i++){
daily_profit[i] = prices[i]-prices[i-1];
if(res + daily_profit[i]>0){
res += daily_profit[i];
if(out<res){
out = res;
}
}
else{
res = 0;
}
cout<<res<<endl;
}
return out;
}
};
Day 17 牛客网练习
1、二分查找
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param nums int整型vector
* @param target int整型
* @return int整型
*/
int search(vector<int>& nums, int target) {
// write code here
int length = nums.size();
int i = 0;
int j = length - 1;
if (length <= 2) {
if (length == 0){
return -1;
}
if (nums[0] == target){
return 0;
}
if (length == 2 && nums[1] == target){
return 1;
}
}
if (target == nums[j]){
return j;
}
while (i < j - 1) {
int wait_num = int((j+i)/2);
if (target < nums[wait_num]) {
j = wait_num;
}
else
{
if (target > nums[wait_num]) {
i = wait_num;
}
else{
return wait_num;
}
}
}
return -1;
}
};
2、升序链表的删除
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) : val(x), next(nullptr) {}
* };
*/
#include <vector>
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类
* @return ListNode类
*/
ListNode* deleteDuplicates(ListNode* head) {
if(head == NULL){
return head;
}
else{
ListNode* p;
p = head;
std::vector<int> wait_array;
wait_array.push_back(p->val);
ListNode* q = new ListNode(p->val);
ListNode* t =q;
while(p->next != NULL){
int wait_element = p->val;
auto it =std::find(wait_array.begin(),wait_array.end(),wait_element);
if (it == wait_array.end()) {
wait_array.push_back(p->val);
t->next = new ListNode(p->val);
cout<<t->next->val<<endl;
t = t->next;
cout<<t->val<<endl;
}
p = p->next;
}
auto it =std::find(wait_array.begin(),wait_array.end(),p->val);
if (it == wait_array.end()) {
wait_array.push_back(p->val);
t->next = new ListNode(p->val);
cout<<t->next->val<<endl;
t = t->next;
cout<<t->val<<endl;
}
return q;
}
}
};
3、删除链表峰值
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) : val(x), next(nullptr) {}
* };
*/
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类
* @return ListNode类
*/
ListNode* deleteNodes(ListNode* head) {
if(head == NULL){
return head;
}
ListNode* p;
p = head;
while(p->next!=NULL){
ListNode* q;
q = p->next;
if (q->next){
if (q->val > p->val && q->val > q->next->val){
p->next = q->next;
}
}
p = p->next;
}
return head;
}
};
Day18
1、合并两个排序的链表
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) : val(x), next(nullptr) {}
* };
*/
#include <cstddef>
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param pHead1 ListNode类
* @param pHead2 ListNode类
* @return ListNode类
*/
ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
ListNode* dummy = new ListNode(0);
ListNode* result = dummy;
ListNode* p;
p = pHead1;
ListNode* q;
q = pHead2;
if(p == NULL&& q == NULL){
return NULL;
}
if(p == NULL&& q != NULL){
return q;
}
if(q == NULL&& p != NULL){
return p;
}
while (p != NULL || q != NULL) {
// cout<<2222<<endl;
if(q == NULL || (p != NULL && p->val <= q->val)){
result->next = new ListNode(p->val);
result = result->next;
if(p->next != NULL){
p = p->next;
}
else{
p = NULL;
}
}
else if ( p == NULL || (q!=NULL && p->val >= q->val)){
cout<<7777<<endl;
result->next = new ListNode(q->val);
result = result->next;
if(q->next != NULL){
q = q->next;
}
else{
q = NULL;
}
}
}
return dummy->next;
}
};
字节笔试
1、部分过
#include <iostream>
#include <vector>
using namespace std;
int main() {
int a;
std::vector<string> wait_array;
while (std::cin>>a) { // 注意 while 处理多个 case
for(int i = 0; i < a; i++){
string t;
std::cin>>t;
wait_array.push_back(t);
}
}
if(a>34){std::cout<<1111111<<wait_array[0]<<endl;}
for(int i=0;i<wait_array.size();i++){
string wait_string = wait_array[i];
// std::cout<<1<<i<<endl;
for(int j = 0;j<wait_string.length()-2;j++){
if(wait_string[j]==wait_string[j+1] && wait_string[j+1]==wait_string[j+2]){
wait_string.erase(j, 1);
--j;
}
if(i<wait_string.length()-3 && wait_string[j]==wait_string[j+1] && wait_string[j+2]==wait_string[j+3] && wait_string[j+2]!=wait_string[j+1]){
wait_string.erase(j+2, 1);
--j;
}
}
std::cout<<wait_string<<endl;
// std::cout<<i<<endl;
}
}
// 64 位输出请用 printf("%lld")