LeetCodet题解——读书笔记(1)

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

Example:

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

(1)问题分析

这是查找问题,在不增加空间消耗的情况下,选择顺序查找,时间复杂度O(n);增加几个变量,可以实现二分查找时间复杂度O(log(n));为每个元素计算一个hash值可以实现hashmap实现常数时间下的查找,时间复杂度O(1)。题目中没有对空间的限制,且数组没排序,所以适合采用hashmap,根据题目要求,应该需要查找两次,第一个值的下标没有约束,应该遍历得到i,第二个值的下标,通过target-num[i]这个约束,用hashmap得到。

(2)代码编写

class Solution{
public:
    vector<int> twosum(vector<int>& nums,int target){
        vector<int> res;
        unordered_map<int,int> second_search;
        for(int i=0;i<nums.size;i++){
            second_search[num[i]]=i;//值为key,下标为value,根据值查找下标
        }
        for(int i=0;i<num.size;i++){
            int sec = target-nums[i];
            if(second_search.count(sec)&&second_search[sec]!=i){
                res.push_back(i);
                res.push_back(second_search[t]);
                break;
            }
        }
        return res;
    }
};

You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8

(1)问题分析

342+564 = 807,之所以从个位开始是方便我们做加法

链表的基本使用

(2)代码编写

struct ListNode {
      int val;  //当前结点的值
      ListNode *next;  //指向下一个结点的指针
      ListNode(int x) : val(x), next(NULL) {}  //初始化当前结点值为x,指针为空
};
class Solution{
    private:
        int numa;
        int numb;
    public:
        ListNode* add(ListNode*l1, ListNode*l2){
            int sum = 0;
            int jin = 0;
            ListNode* p = ListNode(-1);
            ListNode* cur = p;    
            while(l1||l2){
                numa = l1? l1->val:0;
                numb = l2? l2->val:0;
                sum = numa + numb + jin;
                jin = sum/10;
                sum = sum%10;
                cur->next = ListNode(sum);
                cur = cur->next();
                if(l1) l1 = l1->next;
                if(l2) l2 = l2->next;
            }
            if(jin) cur->next = ListNode(jin);
            return p->next;
        }        
};

Given a string, find the length of the longest substring without repeating characters.

Examples:

Given "abcabcbb", the answer is "abc", which the length is 3.

Given "bbbbb", the answer is "b", with the length of 1.

Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequenceand not a substring.

(1)问题分析

遍历一遍字符串,维护一个滑动窗口,向右扩展的时候,判断扩展字符是否出现在滑动窗口中,未出现长度加一,出现过左边界向右平移。判断方式可用哈希表(key为字符,value为下标),当前字母未出现,或者出现位置小于左边界。

(2)代码编写

class Solution{
    public:
        int longestSubString(string s){
            int res=0,left=0,right=0;
            unordered_map<char,int> lastExitChar;
            for(right; right<s.size();right++){
                //不存在这个字符,或者未出现在滑动窗口里
                if(lastExitChar.count(s[right])==0||lastExitChar[s[right]]<left){
                    res = max(res, right-left+1);
                    
                }else{//存在于滑动窗口里
                    left = lastExitChar[s[right]]+1;
                }
                lastExitChar[s[right]] = right;
            }
            return res;
        }
};

There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

(1)问题分析

想要log级别的时间效率,肯定不能遍历,要剪枝,尽可能多的排除掉不可能的选项。实现时采用迭代的方法,传入剪枝后的数组与中值在剪枝后的数组中的排位k。

为了保证思路尽可能简单,代码编写不追求简洁,追求思路符合直观

尽可能将边界情况拉出来单独处理

下标尽可能保持一致都从0开始;有语意,保证逻辑正确

(2)代码编写

class Solution{
public:
    double findmid(vector<int>& num1,vector<int>& num2){
        if((num1.size()+num2.size())%2==1){
            return findkth(num1,0,num2,0,(num1.size()+num2.size())/2-1);//k指下标
        }else{
            return (findkth(num1,0,num2,0,(num1.size()+num2.size())/2-1)+findkth(num1,0,num2,0,(num1.size()+num2.size())/2))/2;
        }
    }
    int findkth(vector<int>& num1,int i,vector<int>& num2,int j,int k){
        if(i==num1.size()){return num2[j+k];}//i是直接用在num1的下标中的
        if(num1.size()>num2.size()){return findkth(num2,j,num1,i,k);}
        if(k==1){return min(num1(0),num2(0));}
        int pa = min(num1.size()-1,i+k/2),pb = j-pa+i+k;
        if(num1[pa]<num2[pb]){
            return findkth(num1,pa,num2,j,k-pa+i);
        }else if(num1[pa]>num2[pb]){
            return findkth(num1,i,num2,pb,k-pb+j);
        }else{
            return num1[pa];
        }
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值