26. 删除数组中的新元素
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
示例 1:
给定数组 nums = [1,1,2],
函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。
示例 2:
给定 nums = [0,0,1,1,1,2,2,3,3,4],
函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。
class Solution {
public int removeDuplicates(int[] nums) {
//i指向要保留的数;
//j遍历整个数组
int i = 0;
for(int j = 1; j < nums.length; j++){
if(nums[i] != nums[j]){
i++;//找到了需要保留的数字,让i后移,腾出位置
nums[i] = nums[j];
}
}
return i+1;
}
}
633. 平方数之和
给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a2 + b2 = c。
示例1:
输入: 5
输出: True
解释: 1 * 1 + 2 * 2 = 5
示例2:
输入: 3
输出: False
class Solution {
public boolean judgeSquareSum(int c) {
int i = 0;
int j = (int) Math.sqrt(c);//取平方根
int target = 0;
//当两数平方和等于2时,i和j都等于1,说明i可以等于j
while(i<=j){
target = i*i+j*j;
if(target == c){
return true;
}else if(target < c){
i++;
}else{
j--;
}
}
return false;
}
}
88. 合并两个有序数组
给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。
说明:
初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
示例:
输入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3
输出: [1,2,2,3,5,6]
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
//归并排序
//因为填充数字在nums1后面,所以从后往前开始遍历
int i1 = m-1;//指向nums1的末尾
int i2 = n-1; //指向nums2的末尾
int index = m+n-1;//指向合并完的数组的末尾
while(i1>=0 && i2>= 0){
//如果nums1大,就填充nums1
if(nums1[i1] > nums2[i2]){
nums1[index--] = nums1[i1--];
}else{
nums1[index--] = nums2[i2--];
}
}
//如果还有数组没有被填充完;
//如果是nums1,就不用管,因为本来就是要填充给nums1的;
//如果是nums2,就全部赋值进去
while(i2>=0){
nums1[index--] = nums2[i2--];
}
}
}
141. 环形链表
给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
思路:遍历,如果遇到null,则一定不是环形;
遍历,如果遇到之前重复的node,则一定是环形。
两种方法解决:快慢指针; HashMap
对应情景:快慢指针,想象是两个运动员在操场上进行长跑,最终肯定会相遇。
HashMap想想运动员每跑几分钟,就拍一下照片,最终肯定有重复场景的两张照片
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public boolean hasCycle(ListNode head) {
//头部处理
//没有节点,不能构成环;
//只有一个结点,也不能构成环
if(head == null || head.next == null) return false;
//快慢指针
//想想自己在运动场进行长跑的场景,
//如果有环,快指针跑两圈,慢指针跑一圈,他们就会相遇
ListNode slow = head;
ListNode fast = head.next;
while(fast != null && fast.next != null){
//此时让快指针走两步
//慢指针走一步
slow = slow.next;
fast = fast.next.next;
//如果相遇,有环
if(slow == fast){
return true;
}
}
return false;
}
}
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
//思路:判断链表有无环;
//找出环的入口
public class Solution {
public ListNode detectCycle(ListNode head) {
//先对链表进行一个自检
if(head == null || head.next == null){
return null;
}
//定义一个快指针,慢指针,判断有无环
//快指针每次走两步,慢指针每次走一步
//设在环状列表入口前有a个节点,环形里面有b个节点,链表总共有a+b个节点
//那么在相遇时,fast指针走了s+nb步
//fast是slow的步数两倍,所以f = s+nb = 2s
//f = 2nb, s= nb,这是第一次相遇时两个指针走的步数
//此时我们想知道环形的入口,s已经走了nb步,我们只要再让s走a步数停下来,
//把这个链表走完,他(s)就从链表口,也就是环形入口那里出来了
//就可以知道链表环状入口在哪里了
//依旧使用双指针的方法,我们定义一个指针,从头开始走,陪着s走a步,在环状入口他们就会第二次相遇
//因为他们一起把链表走完了
ListNode fast = head;
ListNode slow =head;
boolean hascycle = false;
while(fast!=null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
if(fast == slow){
hascycle = true;
break;
//break是跳出本层循环,在本题中,是跳出if语句;
//continue是跳出本次循环,但是下次循环仍继续
}
}
//定义第三个指针,第三个指针和慢指针相遇的地方就是环的入口
if(hascycle){
ListNode third = head;
while(slow != third){
slow = slow.next;
third = third.next;
}
return third;
}
return null;
}
}
来源:CSDN
作者:只不停
链接:https://blog.csdn.net/weixin_42082088/article/details/104373233