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.youkuaiyun.com/weixin_42036647/article/details/89640736
解答是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.youkuaiyun.com/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的差别:
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;
}