LeetCode刷题(2021.8.5)


最近为了将来找工作做准备,所以准备刷刷leetcode上的算法题目,为了边刷题便总结以及将来能够更加方便的回顾,于是做了笔记,不做任何商业用途,如有侵权,请联系删除!

一.两数之和

1.问题描述
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。你可以按任意顺序返回答案。(来源:LeetCode链接:https://leetcode-cn.com/problems/two-sum)

2.解题思路
(1)暴力解题
什么是暴力解题,就是遇到链式的东西,直接从头到尾进行循环并判断,如果满足判断条件,跳出循环,否则继续循环。这种方法的坏处就是时间效率太低。

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

        return result;

    }
};

(2)哈希表方法
在做算法题目的时候,如果碰到数组、字符串等的操作有时候把下标或者值作为哈希表的key或者value,能够有效降低在暴力解题法基础上的时间消耗。

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> result;
        unordered_map<int,int> map1;
        for(int i = 0; i < nums.size(); i++)
        {
            auto it = map1.find(target - nums[i]);
            if(it != map1.end())
            {
                result.push_back(it->second);
                result.push_back(i);
                break;
            }

            map1[nums[i]] = i;
        }

        return result;

    }
};

**注:**哈希表的find函数查找的是键的位置。

二.两数相加

1.问题描述
给你两个非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序的方式存储的,并且每个节点只能存储 一位数字。请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字 0 之外,这两个数都不会以 0 开头。(来源:LeetCode 链接:https://leetcode-cn.com/problems/add-two-numbers)

2.解题思路
这道题中规中矩,没什么难点,唯一要注意的是进位问题。

/**
 * 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* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode* currentNode1 = l1;
        ListNode* currentNode2 = l2;
        ListNode* result = new ListNode;
        ListNode* movePtr = result;
        int enterFlag = 0;

        while(currentNode1 != NULL || currentNode2 != NULL)
        {
            ListNode resCurNode = {0};
            int temp;

            if(currentNode1 == NULL)
            {
                temp = currentNode2->val + enterFlag;
                if(temp >= 10)
                {
                    resCurNode.val = temp - 10;
                    enterFlag = 1;
                }
                else
                {
                    resCurNode.val = temp;
                    enterFlag = 0;
                }

                currentNode2 = currentNode2->next;
            }

            else if(currentNode2 == NULL)
            {
                temp = currentNode1->val + enterFlag;
                if(temp >= 10)
                {
                    resCurNode.val = temp - 10;
                    enterFlag = 1;
                }
                else
                {
                    resCurNode.val = temp;
                    enterFlag = 0;
                }

                currentNode1 = currentNode1->next;
            }

            else
            {
                temp = currentNode1->val + currentNode2->val + enterFlag;
                if(temp >= 10)
                {
                    resCurNode.val = temp - 10;
                    enterFlag = 1;
                }
                else
                {
                    resCurNode.val = temp;
                    enterFlag = 0;
                }

                currentNode1 = currentNode1->next;
                currentNode2 = currentNode2->next;
            }

            movePtr->val = resCurNode.val;
            ListNode* newNode = new ListNode;
            movePtr->next = newNode;
            movePtr = newNode;
        }

        if(enterFlag == 1)
        {
            movePtr->val = 1;
            movePtr->next = NULL;
        }
        else
        {
            ListNode* moveNode = result;
            while(moveNode->next != movePtr)
            {
                moveNode = moveNode->next;
            }

            moveNode->next = NULL;
            delete movePtr;
        }

        return result;
    }
};

三.求最长无重复字符的子串长度

1.问题描述
给定一个字符串s ,请你找出其中不含有重复字符的最长子串 的长度。

2.解题思路
遇到这道题,脑海里的第一个想法就是暴力解题,用每个字符在字符串中进行比较,如果碰到重复的,取它走过的长度,标定为当前最长的字串长度。当然存在很多问题,没有解决,最后参考了别人的滑动窗口的算法。
依次放入字符串的每个字符到一个新的字符串中(滑动窗口),来判断新的字符串中是否含有重复的字符,如果有,滑动窗口左端移动到字符串重复位置的下一个位置,重复此操作。如例题中的 abcabcbb,新字符串 abc 满足题目要求,当窗口向后移动后a进入新字符串,新字符串变成了 abca,这时候不满足要求。所以,我们要移动窗口的左端,让它的左端移动到第一个a的后面,也就是b的位置上,这时候新的字符串变为bca。

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int maxLen = 0;
        int start = 0;
        int end = 0;
        int i = 0;

        if(s.length() == 1) maxLen = 1;

        while( start < s.length() && end < s.length() )
        {
            for(i = start; i < end; i++)
            {
                if(s[i] == s[end])
                {
                    start = i + 1;
                    break;
                }
            }

            maxLen = maxLen < (end - start + 1) ? (end - start + 1) : maxLen;
            end++;
        }

        return maxLen;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值