LeetCode 61 ~ 70

LeetCode 61. 旋转链表

在这里插入图片描述

/**
 * 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* rotateRight(ListNode* head, int k) {
        if(!head) return head;

        int n = 0;
        ListNode *tail;
        for(auto p = head; p; p = p -> next) {
            tail = p;
            n ++ ;
        }

        k %= n;
        if(!k) return head;

        auto p = head;
        for(int i = 0; i < n - k - 1; i ++ ) p = p -> next;
        tail -> next = head;
        head = p -> next;
        p -> next = nullptr;

        return head;
    }
};

LeetCode 62. 不同路径

状态表示:f[i, j]表示机器人坐标共有几种路线可以走到坐标(i, j)
状态计算:f(i, 0) = 1, f(0, j) = 1
f(i, j) = f(i - 1, j) + f(i, j - 1)
在这里插入图片描述

class Solution {
public:
    int uniquePaths(int m, int n) {
        vector<vector<int>> f(m, vector<int>(n, 0));
        f[0][0] = 1;
        for(int i = 0; i < n; i ++ ) f[0][i] = 1;
        for(int i = 0; i < m; i ++ ) f[i][0] = 1;
        for(int i = 1; i < m; i ++ )
            for(int j = 1; j < n; j ++ )
                f[i][j] = f[i - 1][j] + f[i][j - 1];
        
        return f[m - 1][n - 1];
    }
};

LeetCode 63. 不同路径 II

思路如LeetCode 62. 不同路径 ,不同点在于需要处理网格中的障碍物,如果网格中有障碍物,则将障碍物坐标对应的f(i,j)赋值为0,再进行状态计算
在这里插入图片描述
在这里插入图片描述

class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int>>& a) {
        if(a.empty()) return 0;
        int n = a.size(), m = a[0].size();
        vector<vector<int>> f(n, vector<int>(m, 0));
        f[0][0] = 1;

        int t = 1;
        for(int i = 0; i < n; i ++ ) {
            if(a[i][0] == 1) t = 0;
            f[i][0] = t;
        }

        t = 1;
        for(int i = 0; i < m; i ++ ) {
            if(a[0][i] == 1) t = 0;
            f[0][i] = t;
        }
        
        for(int i = 1; i < n; i ++ ) {
            for(int j = 1; j < m; j ++ ) {
                if(a[i][j] == 1) f[i][j] = 0;
                else {
                    f[i][j] = f[i - 1][j] + f[i][j - 1];
                } 
            }
        }

        return f[n - 1][m - 1];
    }
};

LeetCode 64. 最小路径和

状态表示: f(i, j)表示走到坐标(i, j) 的最小路径和
状态计算:f(i, j) = a(i, j) + min(f(i - 1, j), f(i, j - 1))
在这里插入图片描述

class Solution {
public:
    int minPathSum(vector<vector<int>>& f) {
        int n = f.size(), m = f[0].size();
        
        for(int i = 0; i < n; i ++ )
            for(int j = 0; j < m; j ++ )
            {
                if(i == 0 && j == 0) continue;
                else if(i == 0) f[i][j] += f[i][j - 1];
                else if(j == 0) f[i][j] += f[i - 1][j];
                else f[i][j] += min(f[i - 1][j], f[i][j - 1]);
            }

        return f[n - 1][m - 1];
    }
};

LeetCode 65. 有效数字

模拟题,面向测试数据编程

class Solution {
public:
    bool isNumber(string s) {
        int l = 0, r = s.size() - 1;
        while(l <= r && s[l] == ' ') l ++ ;
        while(l <= r && s[r] == ' ') r -- ;
        if(l > r) return false;
        
        s.substr(l, r - l + 1);
        if(s[0] == '+' || s[0] == '-' ) s = s.substr(1);
        if(s.empty()) return false;

        if(s[0] == '.' && (s.size() == 1 || s[1] == 'e' || s[1] == 'E')) 
            return false;

        int dot = 0, e = 0;
        for(int i = 0; i < s.size(); i ++ ) {
            if(s[i] == '.') {
                if(dot > 0 || e > 0) return false;
                dot ++ ;
            } else if(s[i] == 'e' || s[i] == 'E') {
                if(!i || i + 1 == s.size() || e > 0) return false;
                if(s[i + 1] == '+' || s[i + 1] == '-') {
                    if(i + 2 == s.size()) return false;
                    i ++ ;
                }
                e ++ ;
            } else if(s[i] < '0' || s[i] > '9') return false;
        }
        return true;
    }
};

LeetCode 66. 加一

思路类似高精度加法,使用变量t承载进位,每次计算使用t与原有的数字进行相加,将t % 10留在原地,每进一个位 t /= 10

class Solution {
public:
    vector<int> plusOne(vector<int>& nums) {
        int t = 0;
        reverse(nums.begin(), nums.end());
        nums[0] ++ ;
        for(int i = 0; i < nums.size(); i ++ )
        {
            nums[i] += t;
            t = nums[i] / 10;
            nums[i] %= 10;
        }
        if(t) nums.push_back(1);
        reverse(nums.begin(), nums.end());
        return nums;
    }
};

LeetCode 67. 二进制求和

类似高精度加法,将进制数字换成2即可

class Solution {
public:
    string addBinary(string a, string b) {
        reverse(a.begin(), a.end());
        reverse(b.begin(), b.end());

        string c;
        for(int i = 0, t = 0; i < a.size() || i < b.size() || t; i ++ ) {
            if(i < a.size()) t += a[i] - '0';
            if(i < b.size()) t += b[i] - '0';
            c += to_string(t % 2);
            t /= 2;
        }
        reverse(c.begin(), c.end());
        return c;
    }
};

LeetCode 68. 文本左右对齐

  • 先计算出当前行最多能放多少个单词,每个单词之间最少用一个空格隔开(通过双指针计算能放单词的总长度len)
  • 假设当前行最多能放x个单词,需要满足下面3个条件进行放置
  1. 如果当前行是最后一行,则向左对齐(后面多余的用空格补上)
  2. 如果当前行只有一个单词,则向左对齐(后面多余的用空格补上)
  3. 其他情况均左右对齐
class Solution {
public:
    vector<string> fullJustify(vector<string>& words, int maxWidth) {
        vector<string> res;
        for(int i = 0; i < words.size(); i ++ ) {
            int j = i + 1;
            int len = words[i].size();
            while(j < words.size() && len + 1 + words[j].size() <= maxWidth)
                len += 1 + words[j ++ ].size();

            string line;
            if(j == words.size() || j == i + 1) {
                line += words[i];
                for(int k = i + 1; k < j; k ++ ) line += ' ' + words[k];
                while(line.size() < maxWidth) line += ' ';
            } else {
                int cnt = j - i - 1, r = maxWidth - len + cnt;
                line += words[i];
                int k = 0;
                while(k < r % cnt) line += string(r / cnt + 1, ' ') + words[i + k + 1], k ++ ;
                while(k < cnt) line += string(r / cnt, ' ') + words[i + k + 1], k ++ ;
            }

            res.push_back(line);
            i = j - 1;
        }
        return res;
    }
};

LeetCode 69. x 的平方根

二分法。

class Solution {
public:
    int mySqrt(int x) {
        if(x == 0) return 0;
        if(x == 1) return 1;
        int l = 1, r = x >> 1;
        while(l < r)
        {
            int mid = l + r + 1 >> 1;
            if(mid > x / mid) r = mid - 1;
            else l = mid;
        }
        return l;
    }
};

LeetCode 70. 爬楼梯

斐波那契数列,也可以使用DP法进行分析

class Solution {
public:
    int climbStairs(int n) {
        if(n <= 1) return n;
        long long a = 0, b = 1;
        long long sum;
        for(int i = 0; i <= n; i ++ )
        {
            sum = (a + b) % INT_MAX;
            a = b, b = sum;
        }
        return a;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值