1.哈希
1.1 两数之和
代码实现(C++/Java)
cpp
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> map;
for(int i=0;i<nums.size();i++){
if(map.count(target-nums[i])!=0){
return {i,map[target-nums[i]]};
} else {
map[nums[i]]=i;
}
}
return {};
}
};
java
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer,Integer> map=new HashMap<>();
for(int i=0;i<nums.length;i++){
if(map.containsKey(target-nums[i])){
return new int[]{i,map.get(target-nums[i])};
}else {
map.put(nums[i],i);
}
}
return new int[]{};
}
}
1.2 字母异位词分组
代码实现(C++/Java)
cpp
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
vector<vector<string>> res;
unordered_map<string,vector<string>> map;
for(int i=0;i<strs.size();i++){
string t=strs[i];
sort(t.begin(),t.end());
map[t].push_back(strs[i]);
}
for(auto t:map){
res.push_back(t.second);
}
return res;
}
};
java
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
Map<String,List<String>> map=new HashMap<>();
for(String s:strs){
char[] ch=s.toCharArray();
Arrays.sort(ch);
String key=new String(ch);
map.computeIfAbsent(key,k->new ArrayList<>()).add(s);
}
return new ArrayList<>(map.values());
}
}
1.3 最长连续序列
代码实现(C++/Java)
cpp
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
unordered_set<int> set;
for(int i=0;i<nums.size();i++) set.insert(nums[i]);
int res=0;
for(int s:set){
if(!set.contains(s-1)){
int cur=s;
int len=1;
while(set.contains(cur+1)){
cur++;
len++;
}
res=max(res,len);
}
}
return res;
}
};
java
class Solution {
public int longestConsecutive(int[] nums) {
//HashSet(O(n)),TreeSet(nlogn)
HashSet<Integer> set=new HashSet<>();
for(int i=0;i<nums.length;i++) set.add(nums[i]);
int res=0;
for(int t:set){
if(!set.contains(t-1)){
int cur=t;
int len=1;
while(set.contains(cur+1)){
cur++;
len++;
}
res=Math.max(res,len);
}
}
return res;
}
}
2.双指针
2.1 移动0
代码实现(C++/Java)
cpp
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int n=nums.size();
int j=0;
for(int i=0;i<n;i++){
if(nums[i]!=0) nums[j++]=nums[i];
}
for(int i=j;i<n;i++) nums[i]=0;
}
};
java
class Solution {
public void moveZeroes(int[] nums) {
int n=nums.length;
int j=0;
for(int i=0;i<n;i++){
if(nums[i]!=0){
nums[j++]=nums[i];
}
}
for(int i=j;i<n;i++){
nums[i]=0;
}
}
}
2.2 盛水最多的容器
代码实现(C++/Java)
cpp
class Solution {
public:
int maxArea(vector<int>& height) {
int n=height.size();
int l=0,r=n-1;
int res=-1;
while(r>l){
int a=r-l;
int b=min(height[l],height[r]);
res=max(res,a*b);
if(height[l]<height[r]){
l++;
}else {
r--;
}
}
return res;
}
};
java
class Solution {
public int maxArea(int[] height) {
int n=height.length;
int l=0,r=n-1;
int res=-1;
while(r>l){
int a=r-l;
int b=Math.min(height[l],height[r]);
res=Math.max(res,a*b);
if(height[l]<height[r]){
l++;
} else {
r--;
}
}
return res;
}
}
2.3 三数之和
代码实现(C++/Java)
cpp
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;
sort(nums.begin(),nums.end());
for(int i=0;i<nums.size();i++){
if(i>0 && nums[i]==nums[i-1]) continue;
int l=i+1,r=nums.size()-1;
while(r>l){
int sum=nums[i]+nums[l]+nums[r];
if(sum>0){
r--;
} else if(sum<0){
l++;
} else {
vector<int> t;
t.push_back(nums[i]);
t.push_back(nums[l]);
t.push_back(nums[r]);
res.push_back(t);
while(r>l && nums[r]==nums[r-1]) r--;
while(r>l && nums[l]==nums[l+1]) l++;
r--;
l++;
}
}
}
return res;
}
};
java
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res=new ArrayList<>();
Arrays.sort(nums);
for(int i=0;i<nums.length;i++){
if(i>0 && nums[i]==nums[i-1]) continue;
int l=i+1,r=nums.length-1;
while(r>l){
int sum=nums[i]+nums[l]+nums[r];
if(sum>0){
r--;
} else if(sum<0){
l++;
} else {
List<Integer> t=new ArrayList<>();
t.add(nums[i]);
t.add(nums[l]);
t.add(nums[r]);
res.add(t);
while(r>l && nums[r]==nums[r-1]) r--;
while(r>l && nums[l]==nums[l+1]) l++;
r--;
l++;
}
}
}
return res;
}
}
2.4 接雨水
代码实现(C++/Java)
cpp
class Solution {
public:
int trap(vector<int>& height) {
int n=height.size();
int l=0,r=n-1;
int lMax=0,rMax=0;
int res=0;
while(r>l){
if(height[l]<height[r]){
if(height[l]>lMax){
lMax=height[l];
}else {
res+=lMax-height[l];
}
l++;
}else{
if(height[r]>rMax){
rMax=height[r];
} else {
res+=rMax-height[r];
}
r--;
}
}
return res;
}
};
java
class Solution {
public int trap(int[] height) {
int n=height.length;
int l=0,r=n-1;
int lMax=0,rMax=0;
int res=0;
while(r>l){
if(height[l]<height[r]){
if(height[l]>lMax){
lMax=height[l];
}else {
res+=lMax-height[l];
}
l++;
} else {
if(height[r]>rMax){
rMax=height[r];
}else {
res+=rMax-height[r];
}
r--;
}
}
return res;
}
}
3.滑动窗口
3.1 无重复字符的最长子串
代码实现(C++/Java)
cpp
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int n=s.size();
int last[128];
memset(last,-1,sizeof(last));
int l=0;
int res=0;
for(int i=0;i<n;i++){
char c=s[i];
if(last[c]>=l) l=last[c]+1;
last[c]=i;
res=max(res,i-l+1);
}
return res;
}
};
java
class Solution {
public int lengthOfLongestSubstring(String s) {
int n=s.length();
int[] last=new int[128];
Arrays.fill(last,-1);
int res=0;
int l=0;
for(int i=0;i<n;i++){
char c=s.charAt(i);
if(last[c]>=l) l=last[c]+1;
last[c]=i;
res=Math.max(res,i-l+1);
}
return res;
}
}
3.2 找到字符串中所有字母异位词
438. 找到字符串中所有字母异位词 - 力扣(LeetCode)
代码实现(C++/Java)
cpp
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
vector<int> res;
int n=s.size();
int m=p.size();
int ss[26];
int pp[26];
for(int i=0;i<m;i++) pp[p[i]-'a']++;
for(int i=0;i<n;i++){
ss[s[i]-'a']++;
if(i>=m) ss[s[i-m]-'a']--;
if(i>=m-1 && fun(ss,pp)) res.push_back(i-m+1);
}
return res;
}
bool fun(int ss[],int pp[]){
for(int i=0;i<26;i++){
if(ss[i]!=pp[i]) return false;
}
return true;
}
};
java
class Solution {
public List<Integer> findAnagrams(String s, String p) {
List<Integer> res=new ArrayList<>();
int n=s.length();
int m=p.length();
int[] ss=new int[26];
int[] pp=new int[26];
for(int i=0;i<m;i++) pp[p.charAt(i)-'a']++;
for(int i=0;i<n;i++){
ss[s.charAt(i)-'a']++;
if(i>=m) ss[s.charAt(i-m)-'a']--;
if(i>=m-1 && fun(ss,pp)) res.add(i-m+1);
}
return res;
}
public static boolean fun(int[] ss,int[] pp){
for(int i=0;i<26;i++){
if(ss[i]!=pp[i]) return false;
}
return true;
}
}
4.子串
4.1 和为K的子串
代码实现(C++/Java)
cpp
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
unordered_map<int,int> map;
map[0]=1;
int sum=0,res=0;
for(int x:nums){
sum+=x;
if(map.count(sum-k)){
res+=map[sum-k];
}
map[sum]++;
}
return res;
}
};
java
class Solution {
public int subarraySum(int[] nums, int k) {
Map<Integer,Integer> map=new HashMap<>();
map.put(0,1);
int sum=0,res=0;
for(int i=0;i<nums.length;i++){
sum+=nums[i];
if(map.containsKey(sum-k)){
res+=map.get(sum-k);
}
map.put(sum,map.getOrDefault(sum,0)+1);
}
return res;
}
}
4.2 滑动窗口最大值
代码实现(C++/Java)
cpp
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> res;
int n=nums.size();
deque<int> q;
//单调递减队列
for(int i=0;i<n;i++){
if(!q.empty() && q.front()<=i-k){
q.pop_front();
}
while(!q.empty() && nums[i]>=nums[q.back()]){
q.pop_back();
}
q.push_back(i);
if(i>=k-1) res.push_back(nums[q.front()]);
}
return res;
}
};
java
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
int n=nums.length;
int []res=new int[n-k+1];
Deque<Integer> q=new ArrayDeque<>();
int cnt=0;
for(int i=0;i<nums.length;i++){
if(!q.isEmpty() && q.peekFirst()<=i-k){
q.pollFirst();
}
while(!q.isEmpty() && nums[i]>nums[q.peekLast()]){
q.pollLast();
}
q.offer(i);
if(i>=k-1) res[cnt++]=nums[q.peekFirst()];
}
return res;
}
}
4.3 最小覆盖子串
代码实现(C++/Java)
cpp
class Solution {
public:
string minWindow(string s, string t) {
int len=0x3f3f3f3f;
int cur=0;//结果字符串左端点
unordered_map<char,int>win,need;
for(char c:t) need[c]++;
int l=0,r=0;
int cnt=0;
while(r<s.size()){
char c=s[r++];
if(need.count(c)){
win[c]++;
if(win[c]==need[c])cnt++;
}
//开始收缩
while(cnt==need.size()){
if(r-l<len){
len=r-l;
cur=l;
}
c=s[l++];
if(need.count(c)){
if(win[c]==need[c]) cnt--;
win[c]--;
}
}
}
return len==0x3f3f3f3f?"":s.substr(cur,len);
}
};
java
class Solution {
public String minWindow(String s, String t) {
Map<Character,Integer> need=new HashMap<>();
Map<Character,Integer> win=new HashMap<>();
for(char c:t.toCharArray()){
need.put(c,need.getOrDefault(c,0)+1);
}
int len=0x3f3f3f3f;
int cur=0;
int l=0,r=0;
int cnt=0;
while(r<s.length()){
char c=s.charAt(r);
r++;
if(need.containsKey(c)){
win.put(c,win.getOrDefault(c,0)+1);
if(win.get(c).intValue()==need.get(c).intValue()) cnt++;
}
//收缩
while(cnt==need.size()){
if(r-l<len){
len=r-l;
cur=l;
}
char d=s.charAt(l);
l++;
if(need.containsKey(d)){
if(win.get(d).intValue()==need.get(d).intValue()){
cnt--;
}
win.put(d,win.get(d).intValue()-1);
}
}
}
return len == 0x3f3f3f3f ? "" : s.substring(cur, cur + len);
}
}
5.普通数组
5.1 最大子数组和
代码实现(C++/Java)
cpp
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int n=nums.size();
vector<int> dp(n+10,0);
dp[0]=nums[0];
for(int i=1;i<n;i++){
dp[i]=max(dp[i-1]+nums[i],nums[i]);
}
int res=-0x3f3f3f3f;
for(int i=0;i<n;i++) res=max(res,dp[i]);
return res;
}
};
java
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int res=-0x3f3f3f3f;
int sum=0;
for(int i=0;i<nums.size();i++){
sum+=nums[i];
if(sum>res){
res=sum;
}
if(sum<0) sum=0;
}
return res;
}
};
java
class Solution {
public int maxSubArray(int[] nums) {
int res=-0x3f3f3f3f;
int sum=0;
for(int i=0;i<nums.length;i++){
sum+=nums[i];
if(sum>res) res=sum;
if(sum<0) sum=0;
}
return res;
}
}
5.2 合并区间
代码实现(C++/Java)
cpp
class Solution {
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) {
sort(intervals.begin(),intervals.end(),[](const vector<int> &a,vector<int> &b){
return a[0]<b[0];
});
vector<vector<int>> res;
res.push_back(intervals[0]);
for(int i=1;i<intervals.size();i++){
vector<int> &t=res.back();
if(intervals[i][0]<=t[1]){
t[1]=max(t[1],intervals[i][1]);
}else {
res.push_back(intervals[i]);
}
}
return res;
}
};
java
class Solution {
public int[][] merge(int[][] intervals) {
Arrays.sort(intervals,new Comparator<int[]>(){
public int compare(int[] a,int[] b){
return Integer.compare(a[0],b[0]);
}
});
List<int[]> res=new ArrayList<>();
res.add(intervals[0]);
for(int i=1;i<intervals.length;i++){
int[]t=res.get(res.size()-1);
if(intervals[i][0]<=t[1]){
t[1]=Math.max(t[1],intervals[i][1]);
} else {
res.add(intervals[i]);
}
}
int [][]result=new int[res.size()][2];
for(int i=0;i<res.size();i++){
for(int j=0;j<2;j++){
result[i][j]=res.get(i)[j];
}
}
return result;
}
}
5.3 旋转数组
代码实现(C++/Java)
cpp
class Solution {
public:
void rotate(vector<int>& nums, int k) {
vector<int>arr(nums.size(),0);
for(int i=0;i<nums.size();i++){
arr[(i+k)%nums.size()]=nums[i];
}
for(int i=0;i<nums.size();i++){
nums[i]=arr[i];
}
}
};
java
class Solution {
public void rotate(int[] nums, int k) {
int[] arr=new int[nums.length];
for(int i=0;i<nums.length;i++){
arr[(i+k)%nums.length]=nums[i];
}
for(int i=0;i<nums.length;i++){
nums[i]=arr[i];
}
}
}
5.4 除了自身以外数组的乘积
238. 除了自身以外数组的乘积 - 力扣(LeetCode)
代码实现(C++/Java)
cpp
class Solution {
public:
vector<int> productExceptSelf(vector<int>& nums) {
int n=nums.size();
vector<int> pre(n,1);
vector<int> last(n,1);
for(int i=1;i<n;i++){
pre[i]=pre[i-1]*nums[i-1];
}
for(int i=n-2;i>=0;i--){
last[i]=last[i+1]*nums[i+1];
}
vector<int> res(n);
for(int i=0;i<n;i++){
res[i]=pre[i]*last[i];
}
return res;
}
};
java
class Solution {
public int[] productExceptSelf(int[] nums) {
int n=nums.length;
int[] pre=new int[n];
int[] last=new int[n];
Arrays.fill(pre,1);
Arrays.fill(last,1);
for(int i=1;i<n;i++){
pre[i]=pre[i-1]*nums[i-1];
}
for(int i=n-2;i>=0;i--){
last[i]=last[i+1]*nums[i+1];
}
int[] res=new int[n];
for(int i=0;i<n;i++){
res[i]=pre[i]*last[i];
}
return res;
}
}
5.5 缺失的第一个正数
代码实现(C++/Java)
cpp
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
int n=nums.size();
for(int i=0;i<n;i++){
while(nums[i]>=1 && nums[i]<=n && nums[i]!=nums[nums[i]-1]){
swap(nums[i],nums[nums[i]-1]);
}
}
for(int i=0;i<n;i++){
if(nums[i]!=i+1){
return i+1;
}
}
return n+1;
}
};
java
class Solution {
public int firstMissingPositive(int[] nums) {
int n=nums.length;
for(int i=0;i<n;i++){
while(nums[i]>=1 && nums[i]<=n && nums[i]!=nums[nums[i]-1]){
int idx=nums[i]-1;
int t=nums[i];
nums[i]=nums[idx];
nums[idx]=t;
}
}
for(int i=0;i<n;i++){
if(nums[i]!=i+1){
return i+1;
}
}
return n+1;
}
}
6.矩阵
6.1 矩阵置零
代码实现(C++/Java)
cpp
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
int m=matrix.size();
int n=matrix[0].size();
bool fRow=false;
bool fCol=false;
for(int i=0;i<m;i++){
if(matrix[i][0]==0){
fCol=true;
break;
}
}
for(int i=0;i<n;i++){
if(matrix[0][i]==0){
fRow=true;
break;
}
}
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
if(matrix[i][j]==0){
matrix[i][0]=0;
matrix[0][j]=0;
}
}
}
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
if(matrix[i][0]==0 || matrix[0][j]==0){
matrix[i][j]=0;
}
}
}
if(fRow){
for(int i=0;i<n;i++){
matrix[0][i]=0;
}
}
if(fCol){
for(int i=0;i<m;i++){
matrix[i][0]=0;
}
}
}
};
java
class Solution {
public void setZeroes(int[][] matrix) {
int m=matrix.length;
int n=matrix[0].length;
boolean fRow=false;
boolean fCol=false;
for(int i=0;i<m;i++){
if(matrix[i][0]==0){
fCol=true;
break;
}
}
for(int i=0;i<n;i++){
if(matrix[0][i]==0){
fRow=true;
break;
}
}
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
if(matrix[i][j]==0){
matrix[i][0]=0;
matrix[0][j]=0;
}
}
}
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
if(matrix[i][0]==0 || matrix[0][j]==0){
matrix[i][j]=0;
}
}
}
if(fRow){
for(int i=0;i<n;i++){
matrix[0][i]=0;
}
}
if(fCol){
for(int i=0;i<m;i++){
matrix[i][0]=0;
}
}
}
}
6.2 螺旋矩阵
代码实现(C++/Java)
cpp
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
int m=matrix.size();
int n=matrix[0].size();
int l=0,r=n-1,t=0,b=m-1;
vector<int> res;
while(r>=l && b>=t){
for(int i=l;i<=r;i++){
res.push_back(matrix[t][i]);
}
t++;
if(t>b) break;
for(int i=t;i<=b;i++){
res.push_back(matrix[i][r]);
}
r--;
if(l>r) break;
for(int i=r;i>=l;i--){
res.push_back(matrix[b][i]);
}
b--;
for(int i=b;i>=t;i--){
res.push_back(matrix[i][l]);
}
l++;
}
return res;
}
};
java
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> res=new ArrayList<>();
int m=matrix.length;
int n=matrix[0].length;
int l=0,r=n-1,t=0,b=m-1;
while(r>=l && b>=t){
for(int i=l;i<=r;i++){
res.add(matrix[t][i]);
}
t++;
if(t>b) break;
for(int i=t;i<=b;i++){
res.add(matrix[i][r]);
}
r--;
if(l>r) break;
for(int i=r;i>=l;i--){
res.add(matrix[b][i]);
}
b--;
for(int i=b;i>=t;i--){
res.add(matrix[i][l]);
}
l++;
}
return res;
}
}
6.3 旋转图像
代码实现(C++/Java)
cpp
class Solution {
public:
//先转置,再将每一行逆序
void rotate(vector<vector<int>>& matrix) {
int n=matrix.size();
for(int i=0;i<n;i++){
for(int j=i;j<n;j++){
swap(matrix[i][j],matrix[j][i]);
}
}
for(int i=0;i<n;i++){
reverse(matrix[i].begin(),matrix[i].end());
}
}
};
java
class Solution {
public void rotate(int[][] matrix) {
int n=matrix.length;
for(int i=0;i<n;i++){
for(int j=i;j<n;j++){
int t=matrix[i][j];
matrix[i][j]=matrix[j][i];
matrix[j][i]=t;
}
}
for(int i=0;i<n;i++){
int l=0,r=n-1;
while(r>=l){
int t=matrix[i][l];
matrix[i][l]=matrix[i][r];
matrix[i][r]=t;
l++;
r--;
}
}
}
}
6.4 搜索二维矩阵2
代码实现(C++/Java)
cpp
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int m=matrix.size();
int n=matrix[0].size();
if(m==0) return false;
int x=0,y=n-1;
while(y>=0 && x<m){
if(matrix[x][y]==target) return true;
else if(matrix[x][y]>target) y--;
else if(matrix[x][y]<target) x++;
}
return false;
}
};
java
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int m=matrix.length;
int n=matrix[0].length;
int x=0,y=n-1;
while(x<m && y>=0){
if(matrix[x][y]==target) return true;
else if(matrix[x][y]>target) y--;
else if(matrix[x][y]<target) x++;
}
return false;
}
}
7.链表
7.1 相交链表
代码实现(C++/Java)
cpp
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* pa=headA;
ListNode* pb=headB;
while(pa!=pb){
if(pa!=nullptr) pa=pa->next;
else pa=headB;
if(pb!=nullptr) pb=pb->next;
else pb=headA;
}
return pa;
}
};
java
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode pa=headA;
ListNode pb=headB;
while(pa!=pb){
if(pa!=null) pa=pa.next;
else pa=headB;
if(pb!=null) pb=pb.next;
else pb=headA;
}
return pa;
}
}
7.2 反转链表
代码实现(C++/Java)
cpp
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* pre=nullptr;
ListNode* cur=head;
while(cur!=nullptr){
ListNode* next=cur->next;
cur->next=pre;
pre=cur;
cur=next;
}
return pre;
}
};
java
class Solution {
public ListNode reverseList(ListNode head) {
ListNode pre=null;
ListNode cur=head;
while(cur!=null){
ListNode next=cur.next;
cur.next=pre;
pre=cur;
cur=next;
}
return pre;
}
}
7.3 回文链表
代码实现(C++/Java)
cpp
class Solution {
public:
bool isPalindrome(ListNode* head) {
vector<int> arr;
ListNode* cur=head;
while(cur!=nullptr){
arr.push_back(cur->val);
cur=cur->next;
}
int l=0,r=arr.size()-1;
while(r>=l){
if(arr[l]!=arr[r])return false;
l++;
r--;
}
return true;
}
};
java
class Solution {
public boolean isPalindrome(ListNode head) {
ArrayList<Integer> list=new ArrayList<>();
ListNode cur=head;
while(cur!=null){
list.add(cur.val);
cur=cur.next;
}
int l=0,r=list.size()-1;
while(r>=l){
if(list.get(l)!=list.get(r)) return false;
l++;
r--;
}
return true;
}
}
7.4 环形链表
代码实现(C++/Java)
cpp
class Solution {
public:
bool hasCycle(ListNode *head) {
ListNode* fast=head;
ListNode* slow=head;
while(fast!=nullptr && fast->next!=nullptr){
fast=fast->next->next;
slow=slow->next;
if(fast==slow) return true;
}
return false;
}
};
java
public class Solution {
public boolean hasCycle(ListNode head) {
ListNode fast=head;
ListNode slow=head;
while(fast!=null && fast.next!=null){
fast=fast.next.next;
slow=slow.next;
if(fast==slow) return true;
}
return false;
}
}
7.5 环形链表2
代码实现(C++/Java)
cpp
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* fast=head;
ListNode* slow=head;
while(fast!=nullptr && fast->next!=nullptr){
fast=fast->next->next;
slow=slow->next;
if(fast==slow){
ListNode* t1=head;
ListNode* t2=fast;
while(t1!=t2){
t1=t1->next;
t2=t2->next;
}
return t1;
}
}
return nullptr;
}
};
java
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode fast=head;
ListNode slow=head;
while(fast!=null && fast.next!=null){
fast=fast.next.next;
slow=slow.next;
if(fast==slow){
ListNode t1=head;
ListNode t2=fast;
while(t1!=t2){
t1=t1.next;
t2=t2.next;
}
return t1;
}
}
return null;
}
}
7.6 合并两个有序链表
代码实现(C++/Java)
cpp
class Solution {
public:
ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
ListNode* dummy=new ListNode(-1);
ListNode* cur=dummy;
while(list1!=nullptr && list2!=nullptr){
if(list1->val<list2->val){
cur->next=list1;
list1=list1->next;
}else {
cur->next=list2;
list2=list2->next;
}
cur=cur->next;
}
if(list1!=nullptr) cur->next=list1;
else if(list2!=nullptr) cur->next=list2;
return dummy->next;
}
};
java
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
ListNode dummy=new ListNode(-1);
ListNode cur=dummy;
while(list1!=null && list2!=null){
if(list1.val<list2.val){
cur.next=list1;
list1=list1.next;
} else {
cur.next=list2;
list2=list2.next;
}
cur=cur.next;
}
if(list1!=null) cur.next=list1;
else if(list2!=null) cur.next=list2;
return dummy.next;
}
}
7.7 两数相加
代码实现(C++/Java)
cpp
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* dummy=new ListNode(-1);
ListNode* cur=dummy;
int carry=0;
while(l1!=nullptr || l2!=nullptr || carry!=0){
int sum=carry;
if(l1!=nullptr){
sum+=l1->val;
l1=l1->next;
}
if(l2!=nullptr){
sum+=l2->val;
l2=l2->next;
}
carry=sum/10;
cur->next=new ListNode(sum%10);
cur=cur->next;
}
return dummy->next;
}
};
java
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode dummy=new ListNode(-1);
ListNode cur=dummy;
int carry=0;
while(l1!=null || l2!=null ||carry!=0){
int sum=carry;
if(l1!=null){
sum+=l1.val;
l1=l1.next;
}
if(l2!=null){
sum+=l2.val;
l2=l2.next;
}
carry=sum/10;
cur.next=new ListNode(sum%10);
cur=cur.next;
}
return dummy.next;
}
}
7.8 删除链表的倒数第N个结点
19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)
代码实现(C++/Java)
cpp
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummy=new ListNode(-1);
dummy->next=head;
ListNode* fast=dummy;
ListNode* slow=dummy;
for(int i=1;i<=n+1;i++) fast=fast->next;
while(fast!=nullptr){
fast=fast->next;
slow=slow->next;
}
slow->next=slow->next->next;
return dummy->next;
}
};
java
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy=new ListNode(-1);
dummy.next=head;
ListNode fast=dummy;
ListNode slow=dummy;
for(int i=1;i<=n+1;i++) fast=fast.next;
while(fast!=null){
fast=fast.next;
slow=slow.next;
}
slow.next=slow.next.next;
return dummy.next;
}
}
7.9 两两交换链表中的节点
代码实现(C++/Java)
cpp
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode* dummy=new ListNode(0);
dummy->next=head;
ListNode* cur=dummy;
while(cur->next!=nullptr && cur->next->next!=nullptr){
ListNode* t1=cur->next;
ListNode* t2=cur->next->next->next;
cur->next=cur->next->next;
cur->next->next=t1;
cur->next->next->next=t2;
cur=cur->next->next;
}
return dummy->next;
}
};
java
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dummy=new ListNode(-1);
dummy.next=head;
ListNode cur=dummy;
while(cur.next!=null && cur.next.next!=null){
ListNode t1=cur.next;
ListNode t2=cur.next.next.next;
cur.next=cur.next.next;
cur.next.next=t1;
cur.next.next.next=t2;
cur=cur.next.next;
}
return dummy.next;
}
}
7.10 K个一组反转链表
代码实现(C++/Java)
cpp
class Solution {
public:
ListNode* reverse(ListNode* head){
ListNode* pre=nullptr;
ListNode* cur=head;
while(cur!=nullptr){
ListNode* next=cur->next;
cur->next=pre;
pre=cur;
cur=next;
}
return pre;
}
ListNode* reverseKGroup(ListNode* head, int k) {
ListNode* dummy=new ListNode(-1);
dummy->next=head;
ListNode* pre=dummy;
ListNode* end=dummy;
while(end->next!=nullptr){
for(int i=0;i<k && end!=nullptr;i++){
end=end->next;
}
if(end==nullptr) break;
//分组翻转
ListNode* start=pre->next;
ListNode* next=end->next;
end->next=nullptr;
pre->next=reverse(start);
start->next=next;
pre=start;
end=pre;
}
return dummy->next;
}
};
java
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
ListNode dummy=new ListNode(-1);
dummy.next=head;
ListNode pre=dummy;
ListNode end=dummy;
while(end.next!=null){
for(int i=0;i<k && end!=null;i++){
end=end.next;
}
if(end==null) break;
ListNode start=pre.next;
ListNode next=end.next;
end.next=null;
pre.next=reverse(start);
start.next=next;
pre=start;
end=pre;
}
return dummy.next;
}
public static ListNode reverse(ListNode head){
ListNode pre=null;
ListNode cur=head;
while(cur!=null){
ListNode next=cur.next;
cur.next=pre;
pre=cur;
cur=next;
}
return pre;
}
}
7.11 随机链表的复制
代码实现(C++/Java)
cpp
/*
// 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:
Node* copyRandomList(Node* head) {
//创建新节点 k原节点->v新节点
unordered_map<Node*,Node*> map;
Node* cur=head;
while(cur!=nullptr){
map[cur]=new Node(cur->val);
cur=cur->next;
}
//补充节点元素
cur=head;
while(cur!=nullptr){
map[cur]->next=map[cur->next];
map[cur]->random=map[cur->random];
cur=cur->next;
}
return map[head];
}
};
java
/*
// Definition for a Node.
class Node {
int val;
Node next;
Node random;
public Node(int val) {
this.val = val;
this.next = null;
this.random = null;
}
}
*/
class Solution {
public Node copyRandomList(Node head) {
//创建新节点 k原节点->v新节点
Map<Node,Node> map=new HashMap<>();
Node cur=head;
while(cur!=null){
map.put(cur,new Node(cur.val));
cur=cur.next;
}
cur=head;
while(cur!=null){
map.get(cur).next=map.get(cur.next);
map.get(cur).random=map.get(cur.random);
cur=cur.next;
}
return map.get(head);
}
}
7.12 排序链表
代码实现(C++/Java)
cpp
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* sortList(ListNode* head) {
if(head==nullptr || head->next==nullptr) return head;
ListNode* slow=head;
ListNode* fast=head->next;
while(fast!=nullptr && fast->next!=nullptr){
fast=fast->next->next;
slow=slow->next;
}
ListNode* mid=slow->next;
slow->next=nullptr;
ListNode* l=sortList(head);
ListNode* r=sortList(mid);
return merge(l,r);
}
ListNode* merge(ListNode* l,ListNode* r){
ListNode* dummy=new ListNode(-1);
ListNode* cur=dummy;
while(l!=nullptr && r!=nullptr){
if(l->val<r->val){
cur->next=l;
l=l->next;
}else{
cur->next=r;
r=r->next;
}
cur=cur->next;
}
if(l!=nullptr) cur->next=l;
else if(r!=nullptr) cur->next=r;
return dummy->next;
}
};
java
class Solution {
public ListNode sortList(ListNode head) {
if(head==null || head.next==null) return head;
ListNode slow=head;
ListNode fast=head.next;
while(fast!=null && fast.next!=null){
fast=fast.next.next;
slow=slow.next;
}
ListNode mid=slow.next;
slow.next=null;
ListNode l=sortList(head);
ListNode r=sortList(mid);
return merge(l,r);
}
public static ListNode merge(ListNode l,ListNode r){
ListNode dummy=new ListNode(0);
ListNode cur=dummy;
while(l!=null && r!=null){
if(l.val<r.val){
cur.next=l;
l=l.next;
}else {
cur.next=r;
r=r.next;
}
cur=cur.next;
}
if(l!=null) cur.next=l;
else if(r!=null) cur.next=r;
return dummy.next;
}
}
7.13 合并K个升序链表
代码实现(C++/Java)
cpp
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
if(lists.size()==0 || lists.empty()) return nullptr;
return divide(lists,0,lists.size()-1);
}
ListNode* divide(vector<ListNode*>& lists,int l,int r){
if(l==r) return lists[l];
int mid=l+(r-l)/2;
ListNode* left=divide(lists,l,mid);
ListNode* right=divide(lists,mid+1,r);
return merge(left,right);
}
ListNode* merge(ListNode* l,ListNode* r){
ListNode* dummy=new ListNode(-1);
ListNode* cur=dummy;
while(l!=nullptr && r!=nullptr){
if(l->val<r->val){
cur->next=l;
l=l->next;
}else {
cur->next=r;
r=r->next;
}
cur=cur->next;
}
if(l!=nullptr) cur->next=l;
else if(r!=nullptr) cur->next=r;
return dummy->next;
}
};
java
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if(lists==null || lists.length==0) return null;
ListNode res=divide(lists,0,lists.length-1);
return res;
}
public static ListNode divide(ListNode[]lists,int l,int r){
if(l==r) return lists[l];
int mid=l+(r-l)/2;
ListNode left=divide(lists,l,mid);
ListNode right=divide(lists,mid+1,r);
return merge(left,right);
}
public static ListNode merge(ListNode l,ListNode r){
ListNode dummy=new ListNode(-1);
ListNode cur=dummy;
while(l!=null && r!=null){
if(l.val<r.val){
cur.next=l;
l=l.next;
}else {
cur.next=r;
r=r.next;
}
cur=cur.next;
}
if(l!=null) cur.next=l;
else if(r!=null) cur.next=r;
return dummy.next;
}
}
7.14 LRU缓存
代码实现(C++/Java)
cpp
// 定义双向链表节点
struct DLinkedNode {
int key;
int value;
DLinkedNode* prev;
DLinkedNode* next;
// 构造函数
DLinkedNode() : key(0), value(0), prev(nullptr), next(nullptr) {}
DLinkedNode(int _key, int _value) : key(_key), value(_value), prev(nullptr), next(nullptr) {}
};
class LRUCache {
private:
unordered_map<int, DLinkedNode*> cache; // 哈希表:key -> 节点
DLinkedNode* head; // 虚拟头节点(最近使用)
DLinkedNode* tail; // 虚拟尾节点(最久未使用)
int size; // 当前缓存大小
int capacity; // 缓存容量
// 辅助函数:将节点移到链表头部(标记为最近使用)
void moveToHead(DLinkedNode* node) {
// 先移除节点
removeNode(node);
// 再插入到头部
addToHead(node);
}
// 辅助函数:移除指定节点
void removeNode(DLinkedNode* node) {
node->prev->next = node->next;
node->next->prev = node->prev;
}
// 辅助函数:将节点插入到虚拟头节点之后
void addToHead(DLinkedNode* node) {
node->prev = head;
node->next = head->next;
head->next->prev = node;
head->next = node;
}
// 辅助函数:移除虚拟尾节点的前一个节点(最久未使用),并返回该节点
DLinkedNode* removeTail() {
DLinkedNode* node = tail->prev;
removeNode(node);
return node;
}
public:
// 初始化LRU缓存
LRUCache(int _capacity) : capacity(_capacity), size(0) {
// 创建虚拟头、尾节点,避免空指针处理
head = new DLinkedNode();
tail = new DLinkedNode();
head->next = tail;
tail->prev = head;
}
// 获取key对应的值,不存在返回-1
int get(int key) {
// key不存在
if (!cache.count(key)) {
return -1;
}
// key存在,找到节点并移到头部
DLinkedNode* node = cache[key];
moveToHead(node);
return node->value;
}
// 插入/更新key-value
void put(int key, int value) {
// key不存在
if (!cache.count(key)) {
// 创建新节点
DLinkedNode* node = new DLinkedNode(key, value);
// 加入哈希表
cache[key] = node;
// 插入到链表头部
addToHead(node);
size++;
// 缓存已满,移除最久未使用的节点
if (size > capacity) {
DLinkedNode* removedNode = removeTail();
// 从哈希表中删除
cache.erase(removedNode->key);
// 释放内存(可选,OJ平台不要求但规范)
delete removedNode;
size--;
}
} else {
// key存在,更新值并移到头部
DLinkedNode* node = cache[key];
node->value = value;
moveToHead(node);
}
}
// 析构函数(可选,释放内存)
~LRUCache() {
DLinkedNode* cur = head;
while (cur != nullptr) {
DLinkedNode* next = cur->next;
delete cur;
cur = next;
}
}
};
java
// 双向链表节点
class DLinkedNode {
int key;
int value;
DLinkedNode prev;
DLinkedNode next;
// 无参构造(创建虚拟头/尾节点)
public DLinkedNode() {}
// 带参构造(创建缓存节点)
public DLinkedNode(int key, int value) {
this.key = key;
this.value = value;
}
}
class LRUCache {
private final Map<Integer, DLinkedNode> cache; // 哈希表:key -> 节点
private final DLinkedNode head; // 虚拟头(最近使用)
private final DLinkedNode tail; // 虚拟尾(最久未使用)
private final int capacity;
private int size; // 当前缓存大小
public LRUCache(int capacity) {
this.capacity = capacity;
this.size = 0;
this.cache = new HashMap<>();
// 初始化虚拟头/尾节点
head = new DLinkedNode();
tail = new DLinkedNode();
head.next = tail;
tail.prev = head;
}
// 获取key对应的值
public int get(int key) {
DLinkedNode node = cache.get(key);
if (node == null) {
return -1;
}
// 访问后移到头部(标记为最近使用)
moveToHead(node);
return node.value;
}
// 插入/更新key-value
public void put(int key, int value) {
DLinkedNode node = cache.get(key);
if (node == null) {
// 新建节点
DLinkedNode newNode = new DLinkedNode(key, value);
cache.put(key, newNode);
// 插入到头部
addToHead(newNode);
size++;
// 超过容量,移除最久未使用的节点(尾节点前一个)
if (size > capacity) {
DLinkedNode removedNode = removeTail();
cache.remove(removedNode.key);
size--;
}
} else {
// 更新值并移到头部
node.value = value;
moveToHead(node);
}
}
// 辅助:将节点插入到虚拟头之后
private void addToHead(DLinkedNode node) {
node.prev = head;
node.next = head.next;
head.next.prev = node;
head.next = node;
}
// 辅助:移除指定节点
private void removeNode(DLinkedNode node) {
node.prev.next = node.next;
node.next.prev = node.prev;
}
// 辅助:将节点移到头部(先移除,再插入)
private void moveToHead(DLinkedNode node) {
removeNode(node);
addToHead(node);
}
// 辅助:移除虚拟尾节点的前一个节点(最久未使用)
private DLinkedNode removeTail() {
DLinkedNode node = tail.prev;
removeNode(node);
return node;
}
}
8.二叉树
8.1 二叉树中序遍历
代码实现(C++/Java)
cpp
class Solution {
public:
void midOrder(TreeNode* node,vector<int>& res){
if(node==nullptr) return;
midOrder(node->left,res);
res.push_back(node->val);
midOrder(node->right,res);
}
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
midOrder(root,res);
return res;
}
};
cpp
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> stk;
TreeNode* cur=root;
while(cur!=nullptr || !stk.empty()){
if(cur!=nullptr){
stk.push(cur);
cur=cur->left;
}else {
cur=stk.top();
stk.pop();
res.push_back(cur->val);
cur=cur->right;
}
}
return res;
}
};
java
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res=new ArrayList<>();
Stack<TreeNode> stk=new Stack<>();
TreeNode cur=root;
while(cur!=null || !stk.isEmpty()){
if(cur!=null){
stk.push(cur);
cur=cur.left;
}else{
cur=stk.pop();
res.add(cur.val);
cur=cur.right;
}
}
return res;
}
}
8.2 二叉树的最大深度
代码实现(C++/Java)
cpp
class Solution {
public:
int maxDepth(TreeNode* root) {
if(root==nullptr) return 0;
int l=maxDepth(root->left);
int r=maxDepth(root->right);
int res=max(l,r)+1;
return res;
}
};
java
class Solution {
public int maxDepth(TreeNode root) {
if(root==null) return 0;
int l=maxDepth(root.left);
int r=maxDepth(root.right);
int res=Math.max(l,r)+1;
return res;
}
}
8.3 翻转二叉树
代码实现(C++/Java)
cpp
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if(root==nullptr) return nullptr;
swap(root->left,root->right);
invertTree(root->left);
invertTree(root->right);
return root;
}
};
java
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root==null) return null;
TreeNode t=root.left;
root.left=root.right;
root.right=t;
invertTree(root.left);
invertTree(root.right);
return root;
}
}
8.4 对称二叉树
代码实现(C++/Java)
cpp
class Solution {
public:
bool cp(TreeNode* l,TreeNode* r){
if(l==nullptr && r==nullptr) return true;
else if(l==nullptr && r!=nullptr) return false;
else if(l!=nullptr && r==nullptr) return false;
else if(l->val!=r->val) return false;
else return cp(l->left,r->right) && cp(l->right,r->left);
}
bool isSymmetric(TreeNode* root) {
if(root==nullptr) return true;
return cp(root->left,root->right);
}
};
java
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root==null) return true;
return cp(root.left,root.right);
}
public static boolean cp(TreeNode l,TreeNode r){
if(l==null && r==null) return true;
else if(l==null && r!=null) return false;
else if(l!=null && r==null) return false;
else if(l.val!=r.val) return false;
else return cp(l.left,r.right) && cp(l.right,r.left);
}
}
8.5 二叉树的直径
代码实现(C++/Java)
cpp
class Solution {
public:
int res=0;
int dfs(TreeNode* node){
if(node==nullptr) return 0;
int l=dfs(node->left);
int r=dfs(node->right);
res=max(res,l+r);
return max(l,r)+1;
}
int diameterOfBinaryTree(TreeNode* root) {
dfs(root);
return res;
}
};
java
class Solution {
int res=0;
int dfs(TreeNode node){
if(node==null) return 0;
int l=dfs(node.left);
int r=dfs(node.right);
res=Math.max(res,l+r);
return Math.max(l,r)+1;
}
public int diameterOfBinaryTree(TreeNode root) {
dfs(root);
return res;
}
}
8.6 二叉树的层序遍历
代码实现(C++/Java)
cpp
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
queue<TreeNode*> q;
if(root!=nullptr) q.push(root);
while(!q.empty()){
int size=q.size();
vector<int> level;
for(int i=1;i<=size;i++){
TreeNode* node=q.front();
q.pop();
level.push_back(node->val);
if(node->left!=nullptr) q.push(node->left);
if(node->right!=nullptr) q.push(node->right);
}
res.push_back(level);
}
return res;
}
};
java
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res=new ArrayList<>();
Queue<TreeNode> q=new LinkedList<>();
if(root!=null) q.offer(root);
while(!q.isEmpty()){
int size=q.size();
ArrayList<Integer> level=new ArrayList<>();
for(int i=1;i<=size;i++){
TreeNode node=q.poll();
level.add(node.val);
if(node.left!=null) q.offer(node.left);
if(node.right!=null) q.offer(node.right);
}
res.add(level);
}
return res;
}
}
8.7 将有序数组转为二叉搜索树
108. 将有序数组转换为二叉搜索树 - 力扣(LeetCode)
代码实现(C++/Java)
cpp
class Solution {
public:
//二叉搜索树保证中序遍历有序
TreeNode* build(vector<int> &nums,int l,int r){
if(l>r) return nullptr;
int mid=l+((r-l)>>1);
TreeNode* node=new TreeNode(nums[mid]);
node->left=build(nums,l,mid-1);
node->right=build(nums,mid+1,r);
return node;
}
TreeNode* sortedArrayToBST(vector<int>& nums) {
return build(nums,0,nums.size()-1);
}
};
java
class Solution {
//二叉搜索树保证中序遍历有序
public TreeNode sortedArrayToBST(int[] nums) {
return build(nums,0,nums.length-1);
}
public static TreeNode build(int[]nums,int l,int r){
if(l>r) return null;
int mid=l+((r-l)>>1);
TreeNode node=new TreeNode(nums[mid]);
node.left=build(nums,l,mid-1);
node.right=build(nums,mid+1,r);
return node;
}
}
8.8 验证二叉搜索树
代码实现(C++/Java)
cpp
typedef long long ll;
class Solution {
public:
bool cp(TreeNode* node,ll l,ll r){
if(node==nullptr) return true;
if(node->val<=l || node->val>=r) return false;
//左子树小于当前值,右子树大于当前值
return cp(node->left,l,node->val) && cp(node->right,node->val,r);
}
bool isValidBST(TreeNode* root) {
return cp(root,LLONG_MIN,LLONG_MAX);
}
};
java
class Solution {
public boolean isValidBST(TreeNode root) {
return cp(root,Long.MIN_VALUE,Long.MAX_VALUE);
}
public static boolean cp(TreeNode node,long l,long r){
if(node==null) return true;
else if(node.val<=l || node.val>=r) return false;
return cp(node.left,l,node.val) && cp(node.right,node.val,r);
}
}
8.9 二叉搜索树中第K小的元素
230. 二叉搜索树中第 K 小的元素 - 力扣(LeetCode)
代码实现(C++/Java)
cpp
class Solution {
public:
int cnt,res,kv;
void midOrder(TreeNode* node){
if(node==nullptr) return;
midOrder(node->left);
cnt++;
if(cnt==kv){
res=node->val;
return;
}
midOrder(node->right);
}
int kthSmallest(TreeNode* root, int k) {
cnt=0;
kv=k;
midOrder(root);
return res;
}
};
java
class Solution {
public static int cnt,res,kv;
public int kthSmallest(TreeNode root, int k) {
cnt=0;
kv=k;
midOrder(root);
return res;
}
public static void midOrder(TreeNode node){
if(node==null) return;
midOrder(node.left);
cnt++;
if(cnt==kv){
res=node.val;
return;
}
midOrder(node.right);
}
}
8.10 二叉树的右视图
代码实现(C++/Java)
cpp
class Solution {
public:
vector<int> rightSideView(TreeNode* root) {
vector<int> res;
if(root==nullptr) return res;
queue<TreeNode*> q;
q.push(root);
while(!q.empty()){
int size=q.size();
for(int i=1;i<=size;i++){
TreeNode* node=q.front();
q.pop();
if(i==size) res.push_back(node->val);
if(node->left!=nullptr) q.push(node->left);
if(node->right!=nullptr) q.push(node->right);
}
}
return res;
}
};
java
class Solution {
public List<Integer> rightSideView(TreeNode root) {
List<Integer> res=new ArrayList<>();
if(root==null) return res;
Queue<TreeNode> q=new LinkedList<>();
q.offer(root);
while(!q.isEmpty()){
int size=q.size();
for(int i=1;i<=size;i++){
TreeNode node=q.poll();
if(i==size) res.add(node.val);
if(node.left!=null) q.offer(node.left);
if(node.right!=null) q.offer(node.right);
}
}
return res;
}
}
8.11 二叉树展开为链表
代码实现(C++/Java)
cpp
class Solution {
public:
void preOrder(TreeNode* node,vector<TreeNode*>& res){
if(node==nullptr) return;
res.push_back(node);
preOrder(node->left,res);
preOrder(node->right,res);
}
void flatten(TreeNode* root) {
vector<TreeNode*> res;
preOrder(root,res);
int n=res.size();
for(int i=1;i<n;i++){
TreeNode* pre=res.at(i-1);
TreeNode* cur=res.at(i);
pre->left=nullptr;
pre->right=cur;
}
}
};
java
class Solution {
public void flatten(TreeNode root) {
ArrayList<TreeNode> res=new ArrayList<>();
preOrder(root,res);
int n=res.size();
for(int i=1;i<n;i++){
TreeNode pre=res.get(i-1);
TreeNode cur=res.get(i);
pre.left=null;
pre.right=cur;
}
}
public static void preOrder(TreeNode node,ArrayList<TreeNode> res){
if(node==null) return;
res.add(node);
preOrder(node.left,res);
preOrder(node.right,res);
}
}
8.12 从前序与中序遍历序列造二叉树
105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)
代码实现(C++/Java)
cpp
class Solution {
public:
//中序的值->索引
unordered_map<int,int> map;
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
for(int i=0;i<inorder.size();i++){
map[inorder[i]]=i;
}
return build(preorder,0,preorder.size()-1,
inorder,0,inorder.size()-1);
}
TreeNode* build(vector<int>& preorder,int pl,int pr,
vector<int>& inorder,int il,int ir){
if(pl>pr || il>ir){
return nullptr;
}
//根节点
int rootVal=preorder[pl];
TreeNode* root=new TreeNode(rootVal);
//根节点在中序数组中的索引
int rootIdx=map[rootVal];
//左子树的节点数量
int lcnt=rootIdx-il;
//左子树
root->left=build(preorder,pl+1,pl+lcnt,
inorder,il,rootIdx-1);
//右子树
root->right=build(preorder,pl+lcnt+1,pr,
inorder,rootIdx+1,ir);
return root;
}
};
java
class Solution {
public static Map<Integer,Integer> map;
public TreeNode buildTree(int[] preorder, int[] inorder) {
map=new HashMap<>();
for(int i=0;i<inorder.length;i++){
map.put(inorder[i],i);
}
return build(preorder,0,preorder.length-1,
inorder,0,inorder.length-1);
}
public static TreeNode build(int[]preorder,int pl,int pr,
int[]inorder,int il,int ir){
if(pl>pr || il>ir) return null;
//根节点
int rootVal=preorder[pl];
TreeNode root=new TreeNode(rootVal);
int rootIdx=map.get(rootVal);
int lcnt=rootIdx-il;
//左子树
root.left=build(preorder,pl+1,pl+lcnt,
inorder,il,rootIdx-1);
//右子树
root.right=build(preorder,pl+lcnt+1,pr,
inorder,rootIdx+1,ir);
return root;
}
}
8.13 路径总和3
代码实现(C++/Java)
cpp
class Solution {
public:
int dfs(TreeNode* node,long long targetSum){
if(node==nullptr) return 0;
int cnt=0;
if(node->val==targetSum){
cnt++;
}
cnt+=dfs(node->left,targetSum-node->val);
cnt+=dfs(node->right,targetSum-node->val);
return cnt;
}
int pathSum(TreeNode* root, int targetSum) {
if(root==nullptr) return 0;
int res=dfs(root,targetSum);
res+=pathSum(root->left,targetSum);
res+=pathSum(root->right,targetSum);
return res;
}
};
java
class Solution {
public int pathSum(TreeNode root, int targetSum) {
if(root==null) return 0;
int res=dfs(root,targetSum);
res+=pathSum(root.left,targetSum);
res+=pathSum(root.right,targetSum);
return res;
}
public static int dfs(TreeNode node,long targetSum){
if(node==null) return 0;
int cnt=0;
if(node.val==targetSum) cnt++;
cnt+=dfs(node.left,targetSum-node.val);
cnt+=dfs(node.right,targetSum-node.val);
return cnt;
}
}
8.14 二叉树的最近公共祖先
236. 二叉树的最近公共祖先 - 力扣(LeetCode)
代码实现(C++/Java)
cpp
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root==nullptr) return nullptr;
if(root==p || root==q) return root;
TreeNode* l=lowestCommonAncestor(root->left,p,q);
TreeNode* r=lowestCommonAncestor(root->right,p,q);
if(l!=nullptr && r!=nullptr){
return root;
}else if(l==nullptr){
return r;
}else {
return l;
}
}
};
java
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root==null) return null;
if(root==p || root==q) return root;
TreeNode l=lowestCommonAncestor(root.left,p,q);
TreeNode r=lowestCommonAncestor(root.right,p,q);
if(l!=null && r!=null){
return root;
}else if(l==null){
return r;
}else {
return l;
}
}
}
8.15 二叉树中的最大路径和
124. 二叉树中的最大路径和 - 力扣(LeetCode)
代码实现(C++/Java)
cpp
const int MIN=-0x3f3f3f3f;
class Solution {
public:
int res=MIN;
//以root为根节点的单边最大贡献值
int dfs(TreeNode* root){
if(root==nullptr) return 0;
int l=max(dfs(root->left),0);
int r=max(dfs(root->right),0);
//以当前节点为最高点的最大路径和
int cur=root->val+l+r;
res=max(res,cur);
return root->val+max(l,r);
}
int maxPathSum(TreeNode* root) {
dfs(root);
return res;
}
};
java
class Solution {
public static int res;
public int maxPathSum(TreeNode root) {
res=-0x3f3f3f3f;
dfs(root);
return res;
}
public static int dfs(TreeNode root){
if(root==null) return 0;
int l=Math.max(dfs(root.left),0);
int r=Math.max(dfs(root.right),0);
int cur=root.val+l+r;
res=Math.max(res,cur);
return root.val+Math.max(l,r);
}
}