classSolution{public:boolisValidSudoku(vector<vector<char>>& board){int row[9][10]={0};// 哈希表存储每一行的每个数是否出现过,默认初始情况下,每一行每一个数都没有出现过// 整个board有9行,第二维的维数10是为了让下标有9,和数独中的数字9对应。int col[9][10]={0};// 存储每一列的每个数是否出现过,默认初始情况下,每一列的每一个数都没有出现过int box[9][10]={0};// 存储每一个box的每个数是否出现过,默认初始情况下,在每个box中,每个数都没有出现过。整个board有9个box。for(int i=0; i<9; i++){for(int j =0; j<9; j++){// 遍历到第i行第j列的那个数,我们要判断这个数在其所在的行有没有出现过,// 同时判断这个数在其所在的列有没有出现过// 同时判断这个数在其所在的box中有没有出现过if(board[i][j]=='.')continue;int curNumber = board[i][j]-'0';if(row[i][curNumber])returnfalse;if(col[j][curNumber])returnfalse;if(box[j/3+(i/3)*3][curNumber])returnfalse;
row[i][curNumber]=1;// 之前都没出现过,现在出现了,就给它置为1,下次再遇见就能够直接返回false了。
col[j][curNumber]=1;
box[j/3+(i/3)*3][curNumber]=1;}}returntrue;}};classSolution{public:boolisValidSudoku(vector<vector<char>>& board){bool st[9];// 判断行for(int i =0; i <9; i ++){memset(st,0,sizeof st);for(int j =0; j <9; j ++){if(board[i][j]!='.'){int t = board[i][j]-'1';if(st[t])returnfalse;
st[t]=true;}}}// 判断列for(int i =0; i <9; i ++){memset(st,0,sizeof st);for(int j =0; j <9; j ++){if(board[j][i]!='.'){int t = board[j][i]-'1';if(st[t])returnfalse;
st[t]=true;}}}// 判断小方格for(int i =0; i <9; i +=3)for(int j =0; j <9; j +=3){memset(st,0,sizeof st);for(int x =0; x <3; x ++)for(int y =0; y <3; y ++){if(board[i + x][j + y]!='.'){int t = board[i + x][j + y]-'1';if(st[t])returnfalse;
st[t]=true;}}}returntrue;}};
classSolution{publicbooleanisValidSudoku(char[][] board){// init data
HashMap<Integer, Integer>[] rows =newHashMap[9];
HashMap<Integer, Integer>[] columns =newHashMap[9];
HashMap<Integer, Integer>[] boxes =newHashMap[9];for(int i =0; i <9; i++){
rows[i]=newHashMap<Integer, Integer>();
columns[i]=newHashMap<Integer, Integer>();
boxes[i]=newHashMap<Integer, Integer>();}// validate a boardfor(int i =0; i <9; i++){for(int j =0; j <9; j++){char num = board[i][j];if(num !='.'){int n =(int)num;int box_index =(i /3)*3+ j /3;// keep the current cell value
rows[i].put(n, rows[i].getOrDefault(n,0)+1);
columns[j].put(n, columns[j].getOrDefault(n,0)+1);
boxes[box_index].put(n, boxes[box_index].getOrDefault(n,0)+1);// check if this value has been already seen beforeif(rows[i].get(n)>1|| columns[j].get(n)>1|| boxes[box_index].get(n)>1)returnfalse;}}}returntrue;}}
classSolution:defisValidSudoku(self, board):"""
:type board: List[List[str]]
:rtype: bool
"""# init data
rows =[{}for i inrange(9)]
columns =[{}for i inrange(9)]
boxes =[{}for i inrange(9)]# validate a boardfor i inrange(9):for j inrange(9):
num = board[i][j]if num !='.':
num =int(num)
box_index =(i //3)*3+ j //3# keep the current cell value
rows[i][num]= rows[i].get(num,0)+1
columns[j][num]= columns[j].get(num,0)+1
boxes[box_index][num]= boxes[box_index].get(num,0)+1# check if this value has been already seen beforeif rows[i][num]>1or columns[j][num]>1or boxes[box_index][num]>1:returnFalsereturnTrue
classSolution{public:
string countAndSay(int n){
string s ="1";for(int i =0; i < n -1; i ++){
string t;for(int j =0; j < s.size();){int k = j +1;while(k < s.size()&& s[k]== s[j]) k ++;
t +=to_string(k - j)+ s[j];
j = k;}
s = t;}return s;}};
classSolution:defcountAndSay(self, n:int)->str:
pre =''
cur ='1'# 从第 2 项开始for _ inrange(1, n):# 这里注意要将 cur 赋值给 pre# 因为当前项,就是下一项的前一项。有点绕,尝试理解下
pre = cur
# 这里 cur 初始化为空,重新拼接
cur =''# 定义双指针 start,end
start =0
end =0# 开始遍历前一项,开始描述while end <len(pre):# 统计重复元素的次数,出现不同元素时,停止# 记录出现的次数,while end <len(pre)and pre[start]== pre[end]:
end +=1# 元素出现次数与元素进行拼接
cur +=str(end-start)+ pre[start]# 这里更新 start,开始记录下一个元素
start = end
return cur
classSolution:defcombinationSum(self, candidates: List[int], target:int)-> List[List[int]]:
candidates =sorted(candidates)
ans =[]deffind(s, use, remain):for i inrange(s,len(candidates)):
c = candidates[i]if c == remain:
ans.append(use +[c])if c < remain:
find(i, use +[c], remain - c)if c > remain:return
find(0,[], target)return ans
第四十题:
classSolution{public:
vector<vector<int>> ans;
vector<int> path;
vector<vector<int>>combinationSum2(vector<int>& c,int target){sort(c.begin(), c.end());dfs(c,0, target);return ans;}voiddfs(vector<int>& c,int u,int target){if(target ==0){
ans.push_back(path);return;}if(u == c.size())return;int k = u +1;while(k < c.size()&& c[k]== c[u]) k ++;int cnt = k - u;for(int i =0; c[u]* i <= target && i <= cnt; i ++){dfs(c, k, target - c[u]* i);
path.push_back(c[u]);}for(int i =0; c[u]* i <= target && i <= cnt; i ++){
path.pop_back();}}};
classSolution{
List<int[]> freq =newArrayList<int[]>();
List<List<Integer>> ans =newArrayList<List<Integer>>();
List<Integer> sequence =newArrayList<Integer>();public List<List<Integer>>combinationSum2(int[] candidates,int target){
Arrays.sort(candidates);for(int num : candidates){int size = freq.size();if(freq.isEmpty()|| num != freq.get(size -1)[0]){
freq.add(newint[]{num,1});}else{++freq.get(size -1)[1];}}dfs(0, target);return ans;}publicvoiddfs(int pos,int rest){if(rest ==0){
ans.add(newArrayList<Integer>(sequence));return;}if(pos == freq.size()|| rest < freq.get(pos)[0]){return;}dfs(pos +1, rest);int most = Math.min(rest / freq.get(pos)[0], freq.get(pos)[1]);for(int i =1; i <= most;++i){
sequence.add(freq.get(pos)[0]);dfs(pos +1, rest - i * freq.get(pos)[0]);}for(int i =1; i <= most;++i){
sequence.remove(sequence.size()-1);}}}
classSolution:defcombinationSum2(self, candidates: List[int], target:int)-> List[List[int]]:defdfs(pos:int, rest:int):nonlocal sequence
if rest ==0:
ans.append(sequence[:])returnif pos ==len(freq)or rest < freq[pos][0]:return
dfs(pos +1, rest)
most =min(rest // freq[pos][0], freq[pos][1])for i inrange(1, most +1):
sequence.append(freq[pos][0])
dfs(pos +1, rest - i * freq[pos][0])
sequence = sequence[:-most]
freq =sorted(collections.Counter(candidates).items())
ans =list()
sequence =list()
dfs(0, target)return ans
funccombinationSum2(candidates []int, target int)(ans [][]int){
sort.Ints(candidates)var freq [][2]intfor_, num :=range candidates {if freq ==nil|| num != freq[len(freq)-1][0]{
freq =append(freq,[2]int{num,1})}else{
freq[len(freq)-1][1]++}}var sequence []intvar dfs func(pos, rest int)
dfs =func(pos, rest int){if rest ==0{
ans =append(ans,append([]int(nil), sequence...))return}if pos ==len(freq)|| rest < freq[pos][0]{return}dfs(pos+1, rest)
most :=min(rest/freq[pos][0], freq[pos][1])for i :=1; i <= most; i++{
sequence =append(sequence, freq[pos][0])dfs(pos+1, rest-i*freq[pos][0])}
sequence = sequence[:len(sequence)-most]}dfs(0, target)return}funcmin(a, b int)int{if a < b {return a
}return b
}
第四十一题:
classSolution{public:intfirstMissingPositive(vector<int>& nums){int n = nums.size();if(!n)return1;for(auto& x : nums)if(x != INT_MIN) x --;for(int i =0; i < n; i ++){while(nums[i]>=0&& nums[i]< n && nums[i]!= i && nums[i]!= nums[nums[i]])swap(nums[i], nums[nums[i]]);}for(int i =0; i < n; i ++)if(nums[i]!= i)return i +1;return n +1;}};
classSolution{publicintfirstMissingPositive(int[] nums){int n = nums.length;for(int i =0; i < n;++i){if(nums[i]<=0){
nums[i]= n +1;}}for(int i =0; i < n;++i){int num = Math.abs(nums[i]);if(num <= n){
nums[num -1]=-Math.abs(nums[num -1]);}}for(int i =0; i < n;++i){if(nums[i]>0){return i +1;}}return n +1;}}
classSolution:deffirstMissingPositive(self, nums: List[int])->int:
n =len(nums)for i inrange(n):if nums[i]<=0:
nums[i]= n +1for i inrange(n):
num =abs(nums[i])if num <= n:
nums[num -1]=-abs(nums[num -1])for i inrange(n):if nums[i]>0:return i +1return n +1
funcfirstMissingPositive(nums []int)int{
n :=len(nums)for i :=0; i < n; i++{if nums[i]<=0{
nums[i]= n +1}}for i :=0; i < n; i++{
num :=abs(nums[i])if num <= n {
fmt.Println(num-1)
nums[num -1]=-abs(nums[num -1])}}for i :=0; i < n; i++{if nums[i]>0{return i +1}}return n +1}funcabs(x int)int{if x <0{return-x
}return x
}
第四十二题:
classSolution{public:inttrap(vector<int>& height){
stack<int> stk;int res =0;for(int i =0; i < height.size(); i ++){int last =0;while(stk.size()&& height[stk.top()]<= height[i]){
res +=(height[stk.top()]- last)*(i - stk.top()-1);
last = height[stk.top()];
stk.pop();}if(stk.size()) res +=(i - stk.top()-1)*(height[i]- last);
stk.push(i);}return res;}};
publicinttrap(int[] height){if(height == null || height.length ==0)return0;int ans =0;int size = height.length;int[] left_max =newint[size];int[] right_max =newint[size];
left_max[0]= height[0];for(int i =1; i < size; i++){
left_max[i]= Math.max(height[i], left_max[i -1]);}
right_max[size -1]= height[size -1];for(int i = size -2; i >=0; i--){
right_max[i]= Math.max(height[i], right_max[i +1]);}for(int i =1; i < size -1; i++){
ans += Math.min(left_max[i], right_max[i])- height[i];}return ans;}
classSolution(object):deftrap(self, height):"""
:type height: List[int]
:rtype: int
"""# "两头大小决定中间"的题目,考虑使用单调栈来解决,# 类似于84题"柱状图中最大矩形",但注意两题中所求面积不同导致的代码差异,84题求各最大值,而本题求和
stack =[]# 欲维护一个递减栈,注意我们的栈中保存元素下标
res =0for i inrange(len(height)):# 新比较的元素比栈顶元素大 ---> 栈顶元素的右边界已找到,# 又因为我们维护了一个递减栈,栈顶下面的元素高度也大于他,即栈顶处形成凹陷,可计算面积while stack and height[i]> height[stack[-1]]:# 记录栈顶的元素并出栈,接下来我们已经得知栈顶的左右边界,可计算此元素的面积
top = stack.pop()ifnot stack:break# 把栈顶弹出后栈空,即其左边没有比他大的了,无法接水# 栈顶值面积,宽: 右(即为新比较的元素) - 左(弹出后stack-1即为其左) - 1# 长:左右高柱中较矮的柱子 - 栈顶高度# 每次面积实际上仅仅是"本元素可接的水的面积",又因为出栈,不会重复计算, += 计算总面积。相关面积可参考甜姨动图理解
res +=(i - stack[-1]-1)*(min(height[i], height[stack[-1]])- height[top])
stack.append(i)# 新比较的元素比栈顶元素矮 ---> 未找到右边界,没形成凹陷。 将新比较的元素入该单减栈return res
functrap(height []int)int{var left, right, leftMax, rightMax, res int
right =len(height)-1for left < right {if height[left]< height[right]{if height[left]>= leftMax {//设置左边最高柱子
leftMax = height[left]}else{//右边必定有柱子挡水,所以,遇到所有值小于等于leftMax的,全部加入水池
res += leftMax - height[left]}
left++}else{if height[right]> rightMax {//设置右边最高柱子
rightMax = height[right]}else{//左边必定有柱子挡水,所以,遇到所有值小于等于rightMax的,全部加入水池
res += rightMax - height[right]}
right--}}return res
}