菜鸟学算法

Day0

从来没有想过自己会走ACM类算法道路,我个人算法极弱极弱,但是无奈夏令营有机考,因此开始学习【不一定参加夏令营,但是也想准备,我是真的菜,看了好多参加夏令营大佬们对于机考的侃侃而谈我好方】。

我一直是按照出国留学的要求准备研究生材料的,但是今年形势一般,希望我英语能够早点考出成绩就不用去挤保研这条路。雅思报名822,GRE可能要在家考,还不确定。科研也一般有三篇但是无一作。

废话不多说开始。题目都在LeetCode

给你一个长度为n的整数数组nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于nums中除 nums[i] 之外其余各元素的乘积。

思路:两个数组(其中一个题目已给),另一个数组的第i个数=前一个数组第i个数以外其他数乘积

int n=nums.length, right=1;//知道n,这里right差不多是temp的含义,right保留nums[i+1]到num[n]的乘积
        int res[]=new int[n];//另一个数组长度与前一个一样
        res[0]=1;//初始化另一个数组
        for(int i=1;i<n;i++){  //num[i]左边部分相乘
            res[i]=res[i-1]*nums[i-1];
        }
        for(int i=n-1;i>=0;i--){ //num[i]右边部分相乘
            res[i] *= right; 
            right *= nums[i];
        }
        return res;
给定一个整数数组nums和一个目标值target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

思路:没什么思路,直接循环,但是复杂度比较高

 int n= nums.length;
        for (int i=0; i<n;i++)
        {
            for (int j=1+i;j<n;j++)//不能够从头循环找
            {
                if(nums[i]+nums[j]==target && i!=j)//这里i!=j可省略,因为前面已经从i后面开始循环了
                {
                    return new int[] {i,j};//返回两个变量
                }
            }
        }
        return null;
Day1
给出两个非空的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字0之外,这两个数都不会以0开头。

思路:涉及到数据结构的链表问题
https://blog.csdn.net/weixin_42036647/article/details/89640736
解答是Leetcode里面题解有
Leetcode官方解题图示

	  ListNode *res = new ListNode(-1);//添加虚拟头结点,简化边界情况的判断
            ListNode *cur = res;
            int carry = 0;//表示进位
            while(l1 || l2)
            {
                int n1 = l1 ? l1->val : 0;//l1是否为null,不是则返回其对应值,是则返回0
                int n2 = l2 ? l2->val : 0;//同理
                int sum = n1 + n2 + carry;
                carry = sum / 10;//进位
                cur->next = new ListNode(sum % 10);
                cur = cur->next;
                if(l1) l1 = l1->next;
                if(l2) l2 = l2->next;
            }
            if(carry)  cur->next = new ListNode(1);//如果最高位有进位,在最前面补1;
            return res->next;//返回真正的头结点
给定一个字符串,请你找出其中不含有重复字符的最长子串的长度。

思路:滑动窗口←是最简单的,但是也是难想到的
https://blog.csdn.net/Drifter_Galaxy/article/details/99309997

 class Solution {
    public int lengthOfLongestSubstring(String s) {
        //使用HashSet作为滑动窗口,找出无重复字符的最长子串。
        Set<Character> set=new HashSet<>();
        int ans=0,i=0,j=0;
        //i为滑动窗口的左边,j为右边,ans为长度
        //charAt返回当前指定索引处的字符
        while(i<s.length()&&j<s.length()){
            if(!set.contains(s.charAt(j))){
            //如果没有重复,contain()方法返回true,当且仅当此字符串包含指定的char值序列
                set.add(s.charAt(j++));//将下一个字符加进Hashset里
                ans=Math.max(ans,j-i);//求窗口大小
            }
            else{//如果出现重复
                set.remove(s.charAt(i++));
            }
        }
        return ans;
    }
}

滑动窗口系列算法:适用于寻找各种字符串的子串

注意:

Hashset和HashMap的差别:
distinguish

Day2
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。

思路:题目比较简单,就是一个记录位数,然后求模得到位数的数值

int reverse(int x){
    long int res=0;//类似于temp
    while(x!=0)//reverse x,存在则循环
    //设x=234
    {
        int temp=x%10;//4,3,2
        x=x/10;//23,2,0
        res=res*10+temp;//4,43,432
    }
   if(res>INT_MAX||res<INT_MIN) return 0;
   //这一步必须要有,int占4字节32位,根据二进制编码的规则,INT_MAX = 2^31-1,INT_MIN= -2^31.C/C++中,所有超过该限值的数,都会出现溢出。
   //反转后的数据,有可能大于int最大值,小于int的最小值,如果溢出,则返回0
        return res;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值