• 力扣1-10


    1、两数之和

    题目:

    给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 的那 两个 整数,并返回它们的数组下标。

    你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

    你可以按任意顺序返回答案。

    示例 1:

    输入:nums = [2,7,11,15], target = 9
    输出:[0,1]
    解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
    

    示例 2:

    输入:nums = [3,3], target = 6
    输出:[0,1]
    

    提示:

    • (2 <= nums.length <= 10^3)
    • (-10^9 <= nums[i] <= 10^9)
    • (-10^9 <= target <= 10^9)
    • 只会存在一个有效答案

    思路:

    • 1、暴力求解、两重循环、时间复杂度(O(n^2))
    • 2、哈希表存储、查询除了当前这个数的前一个数、即(target - nums[i])、不存在就把数插入、存在就把下标返回。时间复杂度(O(n))

    代码:

    解法1:

    class Solution {
    public:
        vector<int> twoSum(vector<int>& nums, int target) {
            vector<int> ans;
            for(int i = 0 ; i < nums.size() ; i ++ )
                for(int j = i + 1 ; j < nums.size(); j ++ )
                    if(nums[i] + nums[j] == target)
                    {    
                        ans.push_back(i);
                        ans.push_back(j);
                    }
            return ans;
        }
    };
    

    解法2:

    class Solution {
    public:
        vector<int> twoSum(vector<int>& nums, int target) {
            // 无序哈希表
            unordered_map<int, int> heap;
            for(int i = 0 ; i < nums.size(); i ++ )
            {   
                // 定义num[i]前面那个数
                int r = target - nums[i];
                // 如果存在、返回下标
                if(heap.count(r)) return {heap[r], i}; 
                // 否则将此数的下标存入map中
                heap[nums[i]] = i ;
            }
            return {};
        }
    };
    

    2、两数相加

    给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

    请你将两个数相加,并以相同形式返回一个表示和的链表。

    你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

    示例1:

    输入:l1 = [2,4,3], l2 = [5,6,4]
    输出:[7,0,8]
    解释:342 + 465 = 807.
    

    示例 2:

    输入:l1 = [0], l2 = [0]
    输出:[0]
    

    示例3:

    输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
    输出:[8,9,9,9,0,0,0,1]
    

    思路:

    • 低位到高位、逐位相加、和大于10,保留个位,同时进1.
    • 高位有进位的话、最前面补1

    技巧:

    // 添加一个虚拟头结点
    ListNode *head = new ListNode(-1);
    

    代码:

    class Solution {
    public:
        ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
            // 创建虚拟头节点、并用cur指向
            auto dumpy = new ListNode(-1), cur = dumpy;
            int t = 0;
            while(l1 || l2 || t)
            {
                // 把值先加上
                if(l1) t += l1->val, l1=l1->next;
                if(l2) t += l2->val, l2=l2->next;
                // 倒着放
                cur = cur->next = new ListNode(t%10);
                // 去位
                t /= 10;
            }
            // 返回生成的节点
            return dumpy->next;
        }
    };
    

    3、无重复字符的最长子串

    给定一个字符串,请你找出其中不含有重复字符的最长子串的长度

    示例 1:

    输入: s = "abcabcbb"
    输出: 3 
    解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
    

    示例 2:

    输入: s = "bbbbb"
    输出: 1
    解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。示例 3:
    

    示例3:

    输入: s = "pwwkew"
    输出: 3
    解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
         请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
    

    示例 4:

    输入: s = ""
    输出: 0
    

    提示:

    • (0 leq s.length leq 5 * 10 ^ 4)
    • (s) 由英文字母、数字、符号和空格组成

    思路:

    https://www.acwing.com/solution/content/49/

    代码:

    class Solution {
        public:
        int lengthOfLongestSubstring(string s) {
            unordered_map<char, int> hash;
            int res = 0;
            for(int i = 0, j = 0 ; i < s.size(); i ++ )
            {
                // 将元素放入map中
                hash[s[i]]++;
                // 如果元素重复了
                while(hash[s[i]] > 1)
                {
                    // 剔除这个元素
                    hash[s[j]] --;
                    // j 移动一格
                    j ++ ;
                }
                // 更新最大值
                res = max(res, i - j + 1);
            }
            return res;
        }
    };
    

    4、填坑

    5、最长回文子串

    给你一个字符串 s,找到 s 中最长的回文子串。

    示例 1:

    输入:s = "babad"
    输出:"bab"
    解释:"aba" 同样是符合题意的答案。
    

    示例 2:

    输入:s = "cbbd"
    输出:"bb"
    

    示例 3:

    输入:s = "a"
    输出:"a"
    

    示例 4:

    输入:s = "ac"
    输出:"a"
    

    提示:

    • (1 leq s.length leq 1000)
    • s 仅由数字和英文字母(大写和/或小写)组成

    思路:

    class Solution {
    public:
        string longestPalindrome(string s) {
            string res;
            for(int i = 0 ; i < s.size() ; i ++ )
            {
                int l = i - 1, r = i + 1;	// 奇数
                while(l >= 0 && r < s.size() && s[l] == s[r]) l --, r ++ ;
                if(res.size() < r - l - 1 ) res = s.substr(l + 1, r - l - 1);
    
                l = i, r = i + 1;		// 偶数
                while(l >= 0 && r < s.size() && s[l] == s[r]) l --, r ++ ;
                if(res.size() < r - l - 1 ) res = s.substr(l + 1, r - l - 1);
            }
        return res;       
        }
    };
    

    6、Z 字形变换

    将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。

    比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:

    P   A   H   N
    A P L S I I G
    Y   I   R
    

    之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"

    请你实现这个将字符串进行指定行数变换的函数:

    string convert(string s, int numRows);
    

    示例 1:

    输入:s = "PAYPALISHIRING", numRows = 3
    输出:"PAHNAPLSIIGYIR"
    

    示例 2:

    输入:s = "PAYPALISHIRING", numRows = 4
    输出:"PINALSIGYAHRPI"
    解释:
    P     I    N
    A   L S  I G
    Y A   H R
    P     I
    

    示例 3:

    输入:s = "A", numRows = 1
    输出:"A"
    

    提示:

    • 1 <= s.length <= 1000
    • s 由英文字母(小写和大写)、',''.' 组成
    • 1 <= numRows <= 1000

    思路:

    https://www.acwing.com/solution/content/75/

    时间复杂度(O(n))

    class Solution {
    public:
        string convert(string s, int n) {
            string res;
            if(n == 1) return s;
            for(int i = 0 ; i < n ; i ++ )
            {
                // 第一行和最后一行的情况
                if(i == 0 || i == n - 1){
                    for(int j = i ; j < s.size() ; j += 2 * n - 2)
                        res += s[j];
                } else {
                    // 中间行的情况
                    for(int j = i, k = 2 * n - 2 - i ; j < s.size() || k < s.size() ; j += 2 * n - 2, k += 2 * n - 2)
                    {
                        // j在前、k在后
                        if(j < s.size()) res += s[j];   
                        if(k < s.size()) res += s[k];
                    }
                }
            }
            return res;
        }
    };
    

    7、整数反转

    给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。

    如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。

    假设环境不允许存储 64 位整数(有符号或无符号)。

    示例 1:

    输入:x = 123
    输出:321
    

    示例 2:

    输入:x = -123
    输出:-321
    

    示例 3:

    输入:x = 120
    输出:21
    

    示例 4:

    输入:x = 0
    输出:0
    

    提示:

    (-2^{31} leq x leq 2^{31} - 1)


    思路:

    借助关键代码、容易得到反转后的数字、规定不能用long long存储、需要判定边界问题

    r = r * 10 + x % 10;	// 不断地将r的个位让出来	
    

    注:

    • INT_MAX、INT_MIN 均为C++中整数最大值和最小值
    • C++中的取余->正数取余还是正数、负数取余还是负数。
    • 时间复杂度(O(logn))

    代码

    class Solution {
    public:
        int reverse(int x) {
            int r = 0;
            while(x)
            {
                // 判断边界
                if(r > 0 && r > (INT_MAX - x % 10) / 10) return 0;
                if(r < 0 && r < (INT_MIN - x % 10) / 10) return 0;
                // 让出r的个位
                r = r * 10 + x % 10;
                x /= 10;
            }
            return r;
        }
    };
    

    8、填坑

    9、回文数

    给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。

    回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。例如,121 是回文,而 123 不是。

    示例 1:

    输入:x = 121
    输出:true
    

    示例 2:

    输入:x = -121
    输出:false
    解释:从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
    

    示例 3:

    输入:x = 10
    输出:false
    解释:从右向左读, 为 01 。因此它不是一个回文数。
    

    示例 4:

    输入:x = -101
    输出:false
    

    提示:

    (-2^{31} leq x leq 2^{31} - 1)

    思路:

    • LeetCode第七题整数反转思路做、本题无long long限制
    • 转换成字符串,s.regin(),s.rend()分别是转置后字符串的头和尾
    // 反转做法
    class Solution {
    public:
        bool isPalindrome(int x) {
            if(x < 0) return 0;
            int flag = x;
            long long r = 0;	// 防溢出
            while(x)
            {
                r = r * 10 + x % 10;
                x /= 10;
            }
            return r == flag;
        }
    };
    
    // 字符串做法
    class Solution {
    public:
        bool isPalindrome(int x) {
            if(x < 0) return 0;
            string s = to_string(x);
            return s == string(s.rbegin(), s.rend());
        }
    };
    

    10、填坑

  • 相关阅读:
    移动端页面适配———多方案解析
    折叠面板实现,上传文件进度条,三级联选择器,多级联选择器, 利用layui实现
    php二维数组去重
    php抽奖算法
    JS如何判断json是否为空
    MySQL中GROUP_CONCAT()函数
    ubuntu卸载安装mysql
    ubuntu安装phalcon
    Ubuntu 16.04 设置MySQL远程访问权限
    首次ubuntu给root设置密码
  • 原文地址:https://www.cnblogs.com/xiaofrank/p/14732704.html
Copyright © 2020-2023  润新知