本周每日一题 题目
lc575. 分糖果
lc237. 删除链表中的节点
lc367. 有效的完全平方数
lc1218. 最长定差子序列
lc268. 丢失的数字
11-01 lc575. 分糖果
数组的长度就是糖果的数量
然后数量是平均分配的
题目是希望妹妹能够获得更多种类的糖果(数量一定)
那么对于妹妹来说,尽量是一个种类获得一种 。那么统计种类数x,如果大于n/2,那么就是n/2,否则就是x
class Solution {
public int distributeCandies ( int [ ] candyType) {
Set < Integer > set = new HashSet < > ( ) ;
for ( int num: candyType) set. add ( num) ;
return Math . min ( candyType. length/ 2 , set. size ( ) ) ;
}
}
11-02 lc237. 删除链表中的节点
这题一看挺简单的,仔细看了,也挺简单
不给头结点,只给需要删除的节点,那么直接将下一个值复制过来,然后跳过下一个就OK了
然后这里因为不能处理要删除节点是最终节点的情况,除非给头节点
class Solution {
public void deleteNode ( ListNode node) {
node. val = node. next. val;
node. next = node. next. next;
}
}
11-04 lc367. 有效的完全平方数
二分,没啥好说的
看评论,好多老哥骚操作一个接一个,对不起,我没想到。。。就二分把,也凑合
class Solution {
public boolean isPerfectSquare ( int num) {
long l = 1 , r = num;
while ( l< r) {
long mid = ( l+ r) / 2 ;
if ( mid* mid> num) r = mid- 1 ;
else if ( mid* mid< num) l = mid+ 1 ;
else return true ;
}
return l* l== num;
}
}
11-05 lc1218. 最长定差子序列
这个子序列是不考虑连续的
思路是用map记录前面的数,和前面的数的长度位置,那么我在遍历时,只要看看map中是否有当前数-diff存在即可,在的话,自己的长度就是前面数+1
class Solution {
public int longestSubsequence ( int [ ] arr, int diff) {
Map < Integer , Integer > map = new HashMap < > ( ) ;
int res = 0 ;
for ( int a: arr) {
int cnt = map. getOrDefault ( a- diff, 0 ) + 1 ;
res = Math . max ( cnt, res) ;
map. put ( a, cnt) ;
}
return res;
}
}
11-06 lc268. 丢失的数字
给定一个长度为n的数组,其中数字满足0-n,不重复,则必然缺少一个,求缺少的那个,时间O(n),空间O(1)
这种题一看就是swap
然后因为给的数组不够大,所以java这里没有办法,你n+1个数swap会越界的,所以我这里直接舍弃0,只考虑1-n,将1-n放到数组的0~n-1的位置上
具体的逻辑是,0忽略,不swap。最终看哪个位置上是0,如果没有0,则缺失0
这样做的理由是:如果缺失0,那么剩下的所有数必然满足1~n,刚好能放的下;如果缺失的不是0,则其他的也放的下,0就占一个位置不动
(当然还可以求1~n的累加和-sum(nums)也可以,这个要考虑溢出)
class Solution {
public int missingNumber ( int [ ] nums) {
int n = nums. length;
for ( int i= 0 ; i< n; i++ ) {
while ( nums[ i] != 0 && nums[ i] != i+ 1 ) swap ( nums, i, nums[ i] - 1 ) ;
}
for ( int i= 0 ; i< n; i++ ) {
if ( nums[ i] == 0 ) return i+ 1 ;
}
return 0 ;
}
private void swap ( int [ ] nums, int i, int j) {
int t = nums[ i] ;
nums[ i] = nums[ j] ;
nums[ j] = t;
}
}