剑指18 删除链表的节点
ListNode* deleteNode(ListNode* head, int val) {
if(!head) return head;
if(head->val == val) return head->next;
ListNode* p=head;
while(p->next && p->next->val != val){
p=p->next;
}
if(p->next && p->next->val == val) p->next = p->next->next;
return head;
}
剑指52 两个链表的第一个公共节点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
/*走过你来时的路,直到我们相遇*/
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* l1=headA;
ListNode* l2=headB;
while(l1!=l2){
l1= l1!=NULL? l1->next:headB;
l2= l2!=NULL? l2->next:headA;
}
return l1;
}
面试题 02.02. 返回倒数第 k 个节点
int kthToLast(ListNode* head, int k) {
ListNode* slow=head, *fast=head;
while(--k)
fast=fast->next;
while(fast!=NULL&&fast->next!=NULL){
slow=slow->next;
fast=fast->next;
}
return slow->val;
}
344. 反转字符串
void reverseString(vector<char>& s) {
int left=0;
int right=s.size()-1;
while(left<right){
// swap (nums[left],nums[right])
char temp = s[left];
s[left]=s[right];
s[right]=temp;
left++;
right--;
}
}
剑指 Offer 32 - I. 从上到下打印二叉树
vector<int> levelOrder(TreeNode* root) {
vector<int> res;
if(root==nullptr) return res;
queue<TreeNode*> q;
q.push(root); //根入队
while(!q.empty()){ //此处不是 if ,是 while
TreeNode* t=q.front(); //出队
q.pop();
res.push_back(t->val); //出队时记录
if(t->left) q.push(t->left); //左子节点入队
if(t->right) q.push(t->right); //右子节点入队
}
return res;
}
剑指 Offer 25. 合并两个排序的链表
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if(l1==NULL) return l2;
if(l2==NULL) return l1;
if(l1->val<l2->val){
l1->next=mergeTwoLists(l1->next,l2);
return l1;
}
else{
l2->next=mergeTwoLists(l1,l2->next);
return l2;
}
}
783. 二叉搜索树节点最小距离
int prev, ans = INT_MAX;
int minDiffInBST(TreeNode* root) {
Inorder(root);
return ans;
}
void Inorder(TreeNode* root) {
if(root == NULL) return;
Inorder(root->left);
if(prev) // 若前置节点值不为空,则计算当前最小距离
ans = min(ans, root->val-prev);
prev = root->val; // 更新前置节点值
Inorder(root->right);
}
剑指 Offer 50. 第一个只出现一次的字符
char firstUniqChar(string s) {
if(s==" ")
return ' ';
unordered_map<char,int> m;
for(int i=0;i<s.size();i++){
m[s[i]]++;
}
for(int i=0;i<s.size();i++){
if(m[s[i]]==1)
return s[i];
}
return ' ';
}
剑指 Offer 03. 数组中重复的数字
int findRepeatNumber(vector<int>& nums){
for(int i=0;i<nums.size();++i){
while(i!=nums[i]){
if(nums[i]==nums[nums[i]]){
return nums[i];
}
else{
swap(nums[i],nums[nums[i]]);
}
}
}
return 0;//不能少
}
62. 不同路径
int uniquePaths(int m, int n) {
vector<vector<int>> dp(m+1,vector<int>(n+1));
//为了接下来m,n从1起,申请了一个m+1*n+1的空间
dp[0][1]=1;
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
}
return dp[m][n];
}
剑指 Offer 13. 机器人的运动范围
//计算两个坐标数字的和
int sum(int i, int j){
int sum=0;
while(i!=0){
sum+=i%10;
i/=10;
}
while(j!=0){
sum+=j%10;
j/=10;
}
return sum;
}
int dfs(int i, int j, int m, int n, int k, vector<vector<int>> &visited){
//i >= m || j >= n是边界条件的判断,k < sum(i, j)判断当前格子坐标是否
// 满足条件,visited[i][j]判断这个格子是否被访问过
if(i>=m || j>=n || k<sum(i,j) || visited[i][j] )
return 0;
//标注这个格子被访问过
visited[i][j] = true;
//沿着当前格子的右边和下边继续访问
return 1 + dfs(i+1,j,m,n,k,visited)+ dfs(i,j+1,m,n,k,visited);
}
int movingCount(int m, int n, int k) {
vector<vector<int>> visited(m,vector<int>(n,0));
return dfs(0, 0, m, n, k, visited);
}
79. 单词搜索
bool exist(vector<vector<char>>& board, string word) {
if(board.size()==0) return false;
for(int i=0;i<board.size();i++){
for(int j=0;j<board[0].size();j++){
if(dfs(board,word,i,j,0)){
return true;
}
}
}
return false;
}
bool dfs(vector<vector<char>>&board,string & word,int i ,int j, int length ){
if(i>=board.size() || j>=board[0].size() || i<0 || j<0 || length>=word.size() || word[length]!=board[i][j] ){
return false;
}
if(length==word.size()-1 && word[length]==board[i][j]){
return true;
}
char temp=board[i][j];
board[i][j]='0';
bool flag=dfs(board,word,i,j+1,length+1)||dfs(board,word,i,j-1,length+1)||dfs(board,word,i+1,j,length+1)||dfs(board,word,i-1,j,length+1);
board[i][j]=temp; // 标记过的点恢复原状,以便进行下一次搜索
return flag;
}
820. 单词的压缩编码
int minimumLengthEncoding(vector<string>& words) {
int N = words.size();
// 反转每个单词
vector<string> reversed_words;
for (string word : words) {
reverse(word.begin(), word.end());
reversed_words.push_back(word);
}
// 字典序排序
sort(reversed_words.begin(), reversed_words.end());
int res = 0;
for (int i = 0; i < N; i++) {
if (i+1 < N && reversed_words[i+1].find(reversed_words[i]) == 0) {
// 当前单词是下一个单词的前缀,丢弃
} else {
res += reversed_words[i].length() + 1; // 单词加上一个 '#' 的长度
}
}
return res;
}
剑指 Offer 63. 股票的最大利润//华为一面手撕
/*class Solution {
public:
int maxProfit(vector<int>& prices) {
int m = prices.size();
if(m == 0) return 0;
int profit = 0;
int price = INT_MAX;
for(int i=0; i<m; i++){
price=min(price, prices[i]);
profit=max(profit, prices[i]-price);
}
return profit;
}
};*/
class Solution {
public:
int maxProfit(vector<int>& prices) {
if(prices.size() <= 1)
return 0;
int min_price = prices[0], n = prices.size();
vector<int> dp(n, 0);
for(int i = 1; i < n; i++)
{
min_price = min(min_price, prices[i]);
dp[i] = max(dp[i - 1], prices[i] - min_price);
}
return dp[n - 1];
}
};
欢迎关注公众号,干货满满。