zoukankan      html  css  js  c++  java
  • LeetCode--算法,简单级别1

    #include "stdafx.h"
    #include "LeetCode_S.h"
    #include <unordered_map>
    #include <math.h>
    #include <stack>
    
    
    
    using namespace std;
    
    CLeetCode_Solution* CLeetCode_Solution::instance = NULL;
    CLeetCode_Solution::CLeetCode_Solution()
    {
        printf("Hello LeetCode
    ");
    }
    
    
    CLeetCode_Solution::~CLeetCode_Solution()
    {
    }
    
    /*
     给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
    
    你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
    
    示例:
    
    给定 nums = [2, 7, 11, 15], target = 9
    
    因为 nums[0] + nums[1] = 2 + 7 = 9
    所以返回 [0, 1] 
     */
    std::vector<int> CLeetCode_Solution::twoSum(vector<int>& nums, int target)
    {
        unordered_map<int, int> m;
        for (int i = 0; i < nums.size(); i++)
        {
            /*
             *for (int j = i + 1; j < nums.size(); j++)
            {
                if (target == (nums[i] + nums[j]))
                {
                    ret.push_back(i);
                    ret.push_back(j);
                }
            }*/
            if (m.find(target - nums[i]) != m.end())
            {
                return{ m[target - nums[i]], i };
            }
            m[nums[i]] = i;
        }
        return{ 0, 0 };
    }
    
    /*
     给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
    
    示例 1:
    
    输入: 123
    输出: 321
     示例 2:
    
    输入: -123
    输出: -321
    */
    int CLeetCode_Solution::reverse(int x)
    {
        int ret(0);
        while (x != 0)
        {
            int pop = x % 10;
            x /= 10;
            if (ret > INT_MAX / 10 || (ret == INT_MAX / 10 && pop > 7)) return 0;
            if (ret < INT_MIN / 10 || (ret == INT_MIN / 10 && pop - 8)) return 0;
            ret = ret * 10 + pop;
        }
        return ret;
    }
    /*
     *判断回文数
     **/
    bool  CLeetCode_Solution::isPalindrome(int x) {
        if (x < 0)
        {
            return false;
        }
        long long rst(0);
        int x_tmp = x;
        while (x != 0)
        {
            int pop = x % 10;
            rst = rst * 10 + pop;
            x /= 10;
        }
        return (rst == x_tmp);
    }
    //二进制相加
    std::string CLeetCode_Solution::addBinary(string a, string b)
    {
        int al = a.size();
        int bl = b.size();
        while (al < bl)
        {
            a = '0' + a;
            ++al;
        }
        while (bl < al)
        {
            b = '0' + b;
            ++bl;
        }
        for (int j = a.size() - 1; j > 0; j--)
        {
            a[j] = a[j] - '0' + b[j];
            if (a[j] >= '2')
            {
                a[j] = (a[j] - '0') % 2 + '0';
                a[j - 1] = a[j - 1] + 1;
            }
        }
        a[0] = a[0] - '0' + b[0]; //将ab的第0位相加
        if (a[0] >= '2') //若大于等于2,需要进一
        {
            a[0] = (a[0] - '0') % 2 + '0';
            a = '1' + a;
        }
        return a;
    }
    
    //罗马数字转阿拉伯数字
    int CLeetCode_Solution::romanToInt(string s) { //顺序计算 /* unordered_map<string, int> m; m = { { "I", 1 },{ "IV", 3 },{ "IX", 8 },{ "V", 5 },{ "X", 10 },{ "XL", 30 },{ "XC", 80 },{ "L", 50 },{ "C", 100 },{ "CD", 300 },{ "CM", 800 },{ "D", 500 },{ "M", 1000 } }; int ret = m[s.substr(0, 1)]; for (int i = 1; i < s.size(); i++) { string two = s.substr(i - 1, 2); string one = s.substr(i, 1); ret += m[two] ? m[two] : m[one]; } return ret; */ //倒序计算(速度和内存更佳),从后面往前面取值,每次取一个符号,如果j的值比j+1大时,则ret减去j的值(罗马计算的规则) /* *输入: "LVIII" 输出: 58 解释: L = 50, V= 5, III = 3.*/ unordered_map<char, int> m; m = { { 'I', 1 },{ 'V', 5 },{ 'X', 10 },{ 'L', 50 },{ 'C', 100 },{ 'D', 500 },{ 'M', 1000 } }; int ret = m[s[s.size() - 1]]; for (int j = s.size() - 2; j >= 0; j--) { int numL = m[s[j]]; int numR = m[s[j + 1]]; if (numL >= numR) ret += numL; else ret -= numL; } return ret; }
    //字符串数组中的最长公共前缀 std::
    string CLeetCode_Solution::longestCommonPrefix(vector<string>& strs) { if (0 == strs.size()) return ""; string strfirst = strs[0]; for (int i = 1; i < strs.size(); i++) { int j = 0; for (; j < strfirst.size() && j < strs[i].size(); j++) { if (strfirst[j] != strs[i][j]) break; } strfirst = strfirst.substr(0, j); if (strfirst.empty()) return ""; } return strfirst; }
    //判断是否有效的括号
    bool CLeetCode_Solution::isValid(string s) { //()[]{} if (s.empty()) return true; if (0 != s.size() % 2) return false; unordered_map<char, char> m = { {'(',')'},{ '[',']' },{ '{','}' } }; stack<char> ret; for (int i = 0; i < s.size(); i++) { if (m.find(s[i])!=m.end()) ret.push(m[s[i]]); else if (ret.empty() || ret.top() != s[i]) return false; else ret.pop(); } if (ret.empty()) return true; else return false; }
    //合并两个有序链表 ListNode
    * CLeetCode_Solution::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; } l2->next = mergeTwoLists(l1, l2->next); return l2; }
    //删除排序数组中的重复项
    int CLeetCode_Solution::removeDuplicates(vector<int>& nums) { /* if (nums.empty()) return 0; int i = 0; for (int j = 1; j < nums.size();++j) { if (nums[j] != nums[i]) { ++i; nums[i] = nums[j]; } } return i + 1;*/ if (nums.empty()) return 0; int val0 = nums[0]; for (vector<int>::iterator iter = nums.begin()+1; iter != nums.end();) { if (val0 == *iter) { iter = nums.erase(iter); } else { val0 = *iter; iter++; } } return nums.size(); } //给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。 int CLeetCode_Solution::removeElement(vector<int>& nums, int val) { int len = nums.size(); int pos = 0; while (pos < len) { if (nums[pos] == val) nums[pos] = nums[--len]; else ++pos; } nums.resize(len); return len; }
    //手写strstr
    int CLeetCode_Solution::strStr(string haystack, string needle) { int n = haystack.size(), m = needle.size();   //减少循环,避免越界 for (int i = 0; i < n-m+1; ++i) { int j = 0; for (;j < m; ++j) {
           //保证ha一起向前推进
    if (haystack[i + j] != needle[j]) break; } if (j == m) return i; } return -1; }

    int CLeetCode_Solution::strStr(string haystack, string needle)
    {
    int n = haystack.size(), m = needle.size();

    
    

    for (int i = 0; i < n-m+1; ++i)
    {
    int j = 0;
    for (;j < m; ++j)
    {
    if (haystack[i + j] != needle[j]) break;
    }
    if (j == m) return i;
    }
    return -1;
    }

    
    

    //有序vector中插入值
    int CLeetCode_Solution::searchInsert(vector<int> &nums, int target)
    {
    if (nums.size() == 0) return 0;
    if (target >= nums[nums.size() - 1]) return nums.size();
    int left(0), right(nums.size() - 1);

    
    

    while (left < right)
    {
    int mid = left + (right - left) / 2;
    if (nums[mid] < target) left = mid + 1;
    else right = mid;
    }
    return left;
    }

    
    

    /*
    *「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。前五项如下:

    
    

    1. 1
    2. 11
    3. 21
    4. 1211
    5. 111221
    1 被读作  "one 1"  ("一个一") , 即 11。
    11 被读作 "two 1s" ("两个一"), 即 21。
    21 被读作 "one 2",  "one 1" ("一个二" ,  "一个一") , 即 1211。

    
    

    给定一个正整数 n(1 ≤ n ≤ 30),输出外观数列的第 n 项。

    
    

    注意:整数序列中的每一项将表示为一个字符串。

    
    

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/count-and-say
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。*/

    
    


    std::string CLeetCode_Solution::countAndSay(int n)
    {
    int i = 1;
    string ret = "1";

    
    

    while (i < n)
    {
    string tmp = "";
    int sum = 1;
    for (int j = 1; j < ret.size(); ++j)
    {
    if (ret[j] == ret[j - 1])
    {
    sum++;
    }
    else
    {
    tmp += to_string(sum);
    tmp += ret[j - 1];
    sum = 1;

    }
    }
    tmp += to_string(sum);
    tmp += ret[ret.length() - 1];
    ret = tmp;
    i++;
    }
    return ret;
    }

    
    

    //vector<int> v = { -2,1,-3,4,-1,2,1,-5,4 };
    int CLeetCode_Solution::maxSubArray(vector<int>& nums)
    {
    /*
    int ret = INT_MIN;

    
    

    for (int i = 0; i < nums.size(); ++i)
    {
    int sum_tmp = 0;
    for (int j = i; j < nums.size(); ++j)
    {
    sum_tmp += nums[j];
    if (ret < sum_tmp)
    {
    ret = sum_tmp;
    }
    }
    }
    return ret;*/
    /*
    int ret = INT_MIN;
    int sum = 0;

    
    

    for (int i = 0; i < nums.size(); ++i)
    {
    sum += nums[i];
    ret = max(ret, sum);
    if (sum < 0)
    {
    sum = 0;
    }
    }
    return ret;*/

    int sum = 0;
    int dp(nums[0]);// 以第i个元素为结尾的一段最大子序和 ,第1个就是第1个前的连续子数组最大值
    int ret = dp;

    
    

    for (int i = 1; i < nums.size(); ++i)
    {
    dp = max(dp + nums[i], nums[i]);//取dp和 dp+第i个的大值
    ret = max(dp, ret);//保持ret是个dp的大值
    }
    return ret;
    }

    
    

    int CLeetCode_Solution::climbStairs(int n)
    {
    //上第i个台阶总方法是上第i-1和i-2台阶的和
    //比如有3台阶,上第3台阶,可以从第1台阶上或者第二台阶上,上第2台阶
    // 可以从第0台阶上,或者第1台阶上,上第一台阶只能从第0台阶上
    if (n < 3) return n;

    int L1(1), L2(2);//前两个台阶可知数量
    int tmp(0);
    for (int i = 3; i <= n; ++n)
    {
    tmp = L1 + L2;
    L1 = L2;
    L2 = tmp;
    }
    return tmp;
    }

    
    

    int CLeetCode_Solution::maxProfit(vector<int>& prices)
    {
    /*
    int ret(0);

    
    

    for (int i = 0; i < prices.size(); ++i)
    {
    int in_p = prices[i];
    for (int j = i+1; j < prices.size();++j)
    {
    int tmp = prices[j] - in_p;
    ret = max(ret, tmp);
    }
    }
    return ret;*/
    /*
    *
    */
    int l_min(prices[0]);//第i天前的买入最小值
    int l_max(0);//利润最大值

    
    

    for (int i = 1; i < prices.size(); ++i)
    {
    l_max = max(l_max, prices[i] - l_min);
    l_min = min(l_min, prices[i]);
    }
    return l_max;
    }

    
    

    //小偷偷钱,不能偷相邻的两个房子
    int CLeetCode_Solution::rob(vector<int>& nums)
    {
    /*
    if (nums.size() == 0) return 0;
    vector<int> dp(nums.size()+1);
    dp[0] = 0;
    dp[1] = nums[0];
    for (int i = 2; i <= nums.size(); i++) {
    dp[i] = max(dp[i - 1], dp[i - 2] + nums[i - 1]);
    }
    return dp[nums.size()];
    */
    if (nums.size() == 0) return 0;
    if (nums.size() == 1) return nums[0];
    if (nums.size() == 2) return max(nums[1], nums[0]);

    int dp[3] = { 0 };
    dp[0] = 0;
    dp[1] = nums[0];

    
    

    for (int i = 2; i < nums.size(); ++i)
    {
    dp[2] = max(dp[0] + nums[i], dp[1]);
    dp[0] = dp[1];
    dp[1] = dp[2];
    }
    return dp[2];
    }

    
    

    //给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次
    ListNode* CLeetCode_Solution::deleteDuplicates(ListNode* head)
    {
    if (head == NULL) return head;

    ListNode* tmp = head;

    while (tmp->next != NULL)
    {
    if (tmp->val != tmp->next->val)
    {
    //往后面走一步
    tmp = tmp->next;
    }
    else
    {
    //删除掉一个点,保留一个数据
    ListNode* tmp1 = tmp->next;
    tmp->next = tmp1->next;
    delete tmp1;
    }
    }
    return head;
    }

    
    

    void CLeetCode_Solution::merge(vector<int>& nums1, int m, vector<int>& nums2, int n)
    {
    int m_ = m - 1;
    int n_ = n - 1;
    int len = m + n - 1;
    while (m_ >= 0 && n_ >= 0)
    {
    nums1[len--] = nums1[m_] > nums2[n_] ? nums1[m_--] : nums2[n_--];
    }

    while (n_ >= 0) nums1[len--] = nums2[n_--]; //最后 nums2有残留就一定是在最前面的 nums1无所谓,因为已经排好序
    }
    /*
    *输入: 1 1
    / /
    2 3 2 3

    
    

    [1,2,3], [1,2,3]

    
    

    输出: true
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
    **/
    bool CLeetCode_Solution::isSameTree(TreeNode* p, TreeNode* q)
    {
    if (p == NULL && q == NULL) return true;
    if (p == NULL || q == NULL) return false;
    if (p->val != q->val) return false;
    return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
    }
    /*
    给定一个二叉树,检查它是否是镜像对称的。

    
    

    例如,二叉树 [1,2,2,3,4,4,3] 是对称的。

    
    

    1
    /
    2 2
    / /
    3 4 4 3
    **/
    bool isSymmetrictmp(TreeNode* q, TreeNode* p)
    {
    if (p == NULL && q == NULL) return true;
    if (p == NULL || q == NULL) return false;

    return (q->val == p->val) && isSymmetrictmp(q->left, p->right) && isSymmetrictmp(q->right, p->left);
    }

    
    

    bool CLeetCode_Solution::isSymmetric(TreeNode* root)
    {
    if (root == NULL) return true;
    //不停的left和right对比就行
    return isSymmetrictmp(root->left, root->right);

    
    

    }
    /*
    *二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

    
    

    说明: 叶子节点是指没有子节点的节点。

    
    

    示例:
    给定二叉树 [3,9,20,null,null,15,7],

    
    

    3
    /
    9 20
    /
    15 7
    */
    int CLeetCode_Solution::maxDepth(TreeNode* root)
    {
    if (root == NULL) return 0;
    int ret_L = 1, ret_R = 1;
    //取所有left和和right的深度
    if (root->left) ret_L += maxDepth(root->left);
    if (root->right) ret_R += maxDepth(root->right);

    
    

    return max(ret_L, ret_R);
    }
    /*
    *给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)

    
    

    例如:
    给定二叉树 [3,9,20,null,null,15,7],

    
    

    3
    /
    9 20
    /
    15 7
    返回其自底向上的层次遍历为:

    
    

    [
    [15,7],
    [9,20],
    [3]
    ]
    */

    
    

    vector<vector<int>> ret;
    void levelOrderBottomTmp(queue<TreeNode*>current)
    {
    queue<TreeNode*>next;
    vector<int> curVal;

    
    

    while (!current.empty())
    {
    TreeNode* top = current.front();
    current.pop();
    curVal.push_back(top->val);

    
    

    if (top->left != NULL) next.push(top->left);
    if (top->right != NULL) next.push(top->right);
    }
    if (!next.empty()) (levelOrderBottomTmp(next));

    
    

    ret.push_back(curVal);
    }

    
    

    vector<vector<int>> CLeetCode_Solution::levelOrderBottom(TreeNode* root) {

    
    

    if (root == NULL) return ret;

    
    

    queue<TreeNode*> next;
    next.push(root);
    levelOrderBottomTmp(next);
    return ret;
    }

     
  • 相关阅读:
    寒假作业3:简化电梯优化
    线段树2
    线段树1
    数字游戏(二)
    P1352 没有上司的舞会
    加分二叉树
    数字转换
    BLO-Blockade
    树上倍增法求LCA
    种西瓜
  • 原文地址:https://www.cnblogs.com/gongkiro/p/12404843.html
Copyright © 2011-2022 走看看