// Date : 2024/01/22 ~ 2024/01/28
022 | #LeetCode.707. | #北岸计划 | 2024/01/22 |
---|
import java.util.List;
class ListNode {
int val;
ListNode prev;
ListNode next;
ListNode(){
this.val = 0;
this.prev = null;
this.next = null;
}
ListNode(int val){
this.val = val;
this.prev = null;
this.next = null;
}
ListNode(int val, ListNode prev, ListNode next){
this.val = val;
this.prev = prev;
this.next = next;
}
}
public class MyLinkedList {
ListNode head;
int length;
public MyLinkedList (){
head = null;
length = 0;
}
public int get(int index) {
boolean lenValid = length > 0;
boolean idxValid = index >= 0 && index < length ;
int result;
if(lenValid && idxValid){
ListNode curr = head;
for(int i=0 ; i<index ; i++){
curr = curr.next;
}
result = curr.val;
}else{
result = -1;
}
return result;
}
public void addAtHead(int val) {
if(length == 0){
head = new ListNode(val);
}else {
int hVal = head.val;
ListNode node = new ListNode(hVal);
head.val = val;
if(length > 1){
node.next = head.next;
head.next.prev = node;
}
head.next = node;
node.prev = head;
}
length++;
}
public void addAtTail(int val) {
ListNode node = new ListNode(val);
if (head == null) {
head = node;
} else {
ListNode cur = head;
while (cur.next != null) {
cur = cur.next;
}
cur.next = node;
node.prev = cur;
}
length++;
}
public void addAtIndex(int index, int val) {
if (index < 0 || index > length) {
return; // 索引无效,不执行插入操作
}
if (index == 0) {
addAtHead(val); // 在头部插入节点
} else if (index == length) {
addAtTail(val); // 在尾部插入节点
} else {
ListNode newNode = new ListNode(val);
ListNode curr = head;
int count = 0;
while (count < index - 1) {
curr = curr.next;
count++;
}
newNode.prev = curr;
newNode.next = curr.next;
curr.next.prev = newNode;
curr.next = newNode;
length++;
}
}
public void deleteAtIndex(int index) {
boolean lenValid = length > 0;
boolean idxValid = index >= 0 && index < length ;
ListNode dummy = new ListNode();
dummy.next = head;
// head.prev = dummy; 不应该有这一句
ListNode cur = head;
ListNode pre = dummy;
if(lenValid && idxValid){
if(index == 0){
head = head.next;
}else{
for(int i=0 ; i<index ; i++){
cur = cur.next;
pre = pre.next;
}
pre.next = pre.next.next;
cur.prev = cur.prev.prev;
}
length--;
}
}
}
023 | #LeetCode.35. | #北岸计划 | 2024/01/23 |
---|
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n)
的算法。
class Solution {
public int searchInsert(int[] nums, int target) {
int length = nums.length;
int left = 0;
int right = length-1;
int result;
while(right - left > 1){
int mid = (left + right)/2;
if(nums[mid] > target){
right = mid;
}else if(nums[mid] < target){
left = mid;
}else{
return mid;
}
}
boolean found = nums[left] == target || nums[right] == target;
boolean internal = nums[left] < target && nums[right] > target;
if(found){
result = nums[left] == target ? left : right;
}else{
if(internal){
result = right;
}else{
result = nums[right] < target ? right+1 : left;
}
}
return result;
}
}
024 | #LeetCode.34. | #北岸计划 | 2024/01/24 |
---|
给你一个按照非递减顺序排列的整数数组 nums
,和一个目标值 target
。请你找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target
,返回 [-1, -1]
。
你必须设计并实现时间复杂度为 O(log n)
的算法解决此问题。
class Solution {
void searchNearBy(int[] result,int[] nums,int target,int length,int pos){
while(nums[pos] == target){
if(--pos == -1){
break;
}
}
result[0] = ++pos;
while(nums[pos] == target){
if(++pos == length){
break;
}
}
result[1] = --pos;
}
public int[] searchRange(int[] nums, int target) {
int length = nums.length;
int[] result = {-1,-1};
if(length == 0) return result;
int left = 0;
int right = length - 1;
while(right - left > 1){
int mid = (left + right) / 2;
if(nums[mid] < target){
left = mid;
}else if(nums[mid] > target){
right = mid;
}else{
searchNearBy(result,nums,target,length,mid);
return result;
}
}
boolean found = nums[left] == target || nums[right] == target;
boolean internal = nums[left] < target && nums[right] > target;
if(found){
if(nums[left] == target){
searchNearBy(result,nums,target,length,left);
}else{
searchNearBy(result,nums,target,length,right);
}
}else{
// if(internal){
// result = right;
// }else{
// result = nums[right] < target ? right+1 : left;
// }
}
System.out.println(result[0]+"...."+result[1]);
return result;
}
}
025 | #LeetCode.69. | #北岸计划 | 2024/01/25 |
---|
给你一个非负整数 x
,计算并返回 x
的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
**注意:**不允许使用任何内置指数函数和算符,例如 pow(x, 0.5)
或者 x ** 0.5
。
class Solution {
public int mySqrt(int x) {
if (x == 0) return 0;
long left = 0;
long right = x;
while (left < right) {
long mid = left + (right - left + 1) / 2;
if (mid * mid > x) {
right = mid - 1;
} else {
left = mid;
}
}
return (int) left;
}
}
026 | #LeetCode.XX. | #北岸计划 | 2024/01/26 |
---|
class Solution {
public int removeDuplicates(int[] nums) {
if(nums == null || nums.length == 0) return 0;
int left = 0;
int right = 1;
while(right < nums.length){
if(nums[left] != nums[right]){
if(right - left > 1){
nums[left + 1] = nums[right];
}
left++;
}
right++;
}
return left + 1;
}
}
027 | #LeetCode.367. | #北岸计划 | 2024/01/26 |
---|
给你一个正整数 num
。如果 num
是一个完全平方数,则返回 true
,否则返回 false
。
完全平方数 是一个可以写成某个整数的平方的整数。换句话说,它可以写成某个整数和自身的乘积。
不能使用任何内置的库函数,如 sqrt
。
class Solution {
int mySqrt(int x) {
if (x == 0) return 0;
long left = 0;
long right = x;
while (left < right) {
long mid = left + (right - left + 1) / 2;
if (mid * mid > x) {
right = mid - 1;
} else {
left = mid;
}
}
return (int) left;
}
public boolean isPerfectSquare(int num) {
return mySqrt(num)*mySqrt(num) == num;
}
}
028 | #LeetCode.283. | #北岸计划 | 2024/01/27 |
---|
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
class Solution {
public void moveZeroes(int[] nums) {
int length = nums.length;
int j = 0;
for(int i=0 ; i<length ; i++) {
if(nums[i]!=0) {
nums[j++] = nums[i];
}
}
for(int i=j ; i<length ; i++) {
nums[i] = 0;
}
}
}
029 | #LeetCode.206. | #北岸计划 | 2024/01/27 |
---|
给你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
class Solution{
public ListNode reverseList(ListNode head) {
if(head == null || head.next == null){
return head;
}
ListNode pre = new ListNode();
ListNode cur = new ListNode();
ListNode post = new ListNode();
pre = head;
cur = head.next;
post = cur.next;
if(cur.next == null){
cur.next = pre;
pre.next = null;
}else{
boolean flag = true;
while(post != null){
if(flag){
pre.next = null;
flag = false;
}
cur.next = pre;
pre = cur;
cur = post;
post = post.next;
}
cur.next = pre;
}
return cur;
}
}
030 | #LeetCode.24. | #北岸计划 | 2024/01/28 |
---|
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。
你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode curr = head;
List<Integer> list = new ArrayList<>();
if(head == null) return null;
while(curr != null){
list.add(curr.val);
curr = curr.next;
}
int length = list.size();
int idx = 0;
while(idx < length-1){
int temp = list.get(idx);
list.set(idx,list.get(idx+1));
list.set(idx+1,temp);
idx += 2;
}
ListNode newHead = new ListNode(list.get(0));
curr = newHead;
for(int i = 1; i < length; i++) {
curr.next = new ListNode(list.get(i));
curr = curr.next;
}
return newHead;
}
}