力扣19删除链表的倒数第n个节点
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
思路:链表题涉及到位置索引的可以通过设计方法来求链表长度
注意,初始化一个纸箱head的节点列表:ListNode dummy = new ListNode(0,head);
首先现找到倒数第n-1个节点
寻找方法,通过for(int i = 1;i<len-n+1;i++){
cur = cur.next;
}
cur.next = cur.next.next;
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(0,head);
int len = getlength(head);
ListNode cur = dummy;
for(int i = 1;i<len-n+1;i++){
cur = cur.next;
}
cur.next = cur.next.next;
return dummy.next;
}
public int getlength(ListNode head){
int len = 0;
while(head!=null){
len++;
head = head.next;
}
return len;
}
}
力扣225用队列实现栈
队列的基本操作
add和offer都是增加元素 ,add在超出范围时会报错
offer不会理解报错
poll获取并移除队列的头
element获取队列的头 若为空则抛出异常
peek也是获取队列的头,若为空曾返回null
使用队列实现栈的下列操作:
push(x) – 元素 x 入栈
pop() – 移除栈顶元素
top() – 获取栈顶元素
empty() – 返回栈是否为空
注意:
你只能使用队列的基本操作-- 也就是 push to back, peek/pop from front, size, 和 is empty 这些操作是合法的。
你所使用的语言也许不支持队列。 你可以使用 list 或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
你可以假设所有操作都是有效的(例如, 对一个空的栈不会调用 pop 或者 top 操作)。
解答:
在队列中 每送入第n个元素,要将队列的前n-1移出并按送入顺序依次移入序列中,如上图
思路:
首先明确队列先进先出的方式
push: 将队列中总入新元素之后,还要将队列的头元素poll再offer送入队列queue.offer(queue.poll()); 重复queue.size次
pop:每次送出队列的头部元素 queue.poll()
top:queue.peek()操作
empty:queue.isEmpty()
方法二:一个队列
方法一使用了两个队列实现栈的操作,也可以使用一个队列实现栈的操作。
使用一个队列时,为了满足栈的特性,即最后入栈的元素最先出栈,同样需要满足队列前端的元素是最后入栈的元素。
入栈操作时,首先获得入栈前的元素个数 nn,然后将元素入队到队列,再将队列中的前 nn 个元素(即除了新入栈的元素之外的全部元素)依次出队并入队到队列,此时队列的前端的元素即为新入栈的元素,且队列的前端和后端分别对应栈顶和栈底。
由于每次入栈操作都确保队列的前端元素为栈顶元素,因此出栈操作和获得栈顶元素操作都可以简单实现。出栈操作只需要移除队列的前端元素并返回即可,获得栈顶元素操作只需要获得队列的前端元素并返回即可(不移除元素)。
由于队列用于存储栈内的元素,判断栈是否为空时,只需要判断队列是否为空即可。
class MyStack {
Queue<Integer> queue;
/** Initialize your data structure here. */
public MyStack() {
queue = new LinkedList<Integer>();
}
/** Push element x onto stack. */
public void push(int x) {
int n = queue.size();
queue.offer(x);
for(int i=0;i<n;i++){
queue.offer(queue.poll());
}
}
/** Removes the element on top of the stack and returns that element. */
public int pop() {
return queue.poll();
}
/** Get the top element. */
public int top() {
return queue.peek();
}
/** Returns whether the stack is empty. */
public boolean empty() {
return queue.isEmpty();
}
面试题10.01 合并排序的数组
从A[m]开始依次存入B[0]直到B[n]
再排序
给定两个排序后的数组 A 和 B,其中 A 的末端有足够的缓冲空间容纳 B。 编写一个方法,将 B 合并入 A 并排序。
初始化 A 和 B 的元素数量分别为 m 和 n。
示例:
输入:
A = [1,2,3,0,0,0], m = 3
B = [2,5,6], n = 3
输出: [1,2,2,3,5,6]
说明:
class Solution {
public void merge(int[] A, int m, int[] B, int n) {
for (int i = 0; i != n; ++i) {
A[m + i] = B[i];
}
Arrays.sort(A);
}
}
力扣34在排序数组中查找元素的第一个和最后一个位置
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
进阶:
你可以设计并实现时间复杂度为 O(log n) 的算法解决此问题吗?
示例 1:
输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]
示例 2:
输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]
示例 3:
输入:nums = [], target = 0
输出:[-1,-1]
class Solution {
public int[] searchRange(int[] nums, int target) {
int[] arr = new int[2];
arr[0]=-1;
arr[1]=-1;
for(int i=0;i<nums.length;i++){
if(nums[i]==target){
arr[0]=i;
break;
}
}
if(arr[0]==-1){
return arr;
}
arr[1]=arr[0];
for(int i = arr[0]+1;i<nums.length;i++){
if(nums[i]==target){
arr[1]=i;
}
else{
break;
}
}
return arr;
}
}
力扣8字符串转换整数:
请你来实现一个 atoi 函数,使其能将字符串转换成整数。
首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。接下来的转化规则如下:
如果第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字字符组合起来,形成一个有符号整数。
假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成一个整数。
该字符串在有效的整数部分之后也可能会存在多余的字符,那么这些字符可以被忽略,它们对函数不应该造成影响。
假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换,即无法进行有效转换。
在任何情况下,若函数不能进行有效的转换时,请返回 0 。
注意:
本题中的空白字符只包括空格字符 ’ ’ 。
假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231, 231 − 1]。如果数值超过这个范围,请返回 231 − 1 或 −231 。
🙋🙋我来了~~ 最近这几天非常忙,leetcode和公众号的消息不能及时回复见谅!我会抽空一条条回复的!现在先来打卡啦~
这道题目其实出得有点恶心,需要比较仔细才可以通过。当然比这题更恶心的是要需要识别科学计数法,识别二进制(0b01),八进制(012),十六进制(0xab),不知道leetcode会不会丧心病狂出这样的题目(或者已经有了?)。。
这题的做法大概是这样:
去掉前导空格
再是处理正负号
识别数字,注意越界情况。
这道题目如果只是简单地字符串转整数的话,就是简单地 ans = ans * 10 + digit。
但是注意这道题目可能会超过integer的最大表示!
也就是说会在某一步 ans * 10 + digit > Integer.MAX_VALUE。
*10 和 +digit 都有可能越界,那么只要把这些都移到右边去就可以了。
ans > (Integer.MAX_VALUE - digit) / 10 就是越界。
不过我的忠告是,等真正工作以后,尽可能地调用jdk的方法,比如Character.isDigit。如果没有你想要的api,也要尽量使用guava,apache common等常见的utils包,尽量不要自己造轮子,一是这样减少出错的可能,二是比较无脑,保护脑细胞~
下面是代码:
public class Solution {
public int myAtoi(String str) {
char[] chars = str.toCharArray();
int n = chars.length;
int idx = 0;
while (idx < n && chars[idx] == ' ') {
// 去掉前导空格
idx++;
}
if (idx == n) {
//去掉前导空格以后到了末尾了
return 0;
}
boolean negative = false;
if (chars[idx] == '-') {
//遇到负号
negative = true;
idx++;
} else if (chars[idx] == '+') {
// 遇到正号
idx++;
} else if (!Character.isDigit(chars[idx])) {
// 其他符号
return 0;
}
int ans = 0;
while (idx < n && Character.isDigit(chars[idx])) {
int digit = chars[idx] - '0';
if (ans > (Integer.MAX_VALUE - digit) / 10) {
// 本来应该是 ans * 10 + digit > Integer.MAX_VALUE
// 但是 *10 和 + digit 都有可能越界,所有都移动到右边去就可以了。
return negative? Integer.MIN_VALUE : Integer.MAX_VALUE;
}
ans = ans * 10 + digit;
idx++;
}
return negative? -ans : ans;
}
}
力扣15:三数之和
思路
标签:数组遍历
首先对数组进行排序,排序后固定一个数 nums[i]nums[i],再使用左右指针指向 nums[i]nums[i]后面的两端,数字分别为 nums[L]nums[L] 和 nums[R]nums[R],计算三个数的和 sumsum 判断是否满足为 00,满足则添加进结果集
如果 nums[i]nums[i]大于 00,则三数之和必然无法等于 00,结束循环
如果 nums[i]nums[i] == nums[i-1]nums[i−1],则说明该数字重复,会导致结果重复,所以应该跳过
当 sumsum == 00 时,nums[L]nums[L] == nums[L+1]nums[L+1] 则会导致结果重复,应该跳过,L++L++
当 sumsum == 00 时,nums[R]nums[R] == nums[R-1]nums[R−1] 则会导致结果重复,应该跳过,R–R−−
时间复杂度:O(n^2)O(n
2
),nn 为数组长度
代码
class Solution {
public static List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> ans = new ArrayList();
int len = nums.length;
if(nums == null || len < 3) return ans;
Arrays.sort(nums); // 排序
for (int i = 0; i < len ; i++) {
if(nums[i] > 0) break; // 如果当前数字大于0,则三数之和一定大于0,所以结束循环
if(i > 0 && nums[i] == nums[i-1]) continue; // 去重
int L = i+1;
int R = len-1;
while(L < R){
int sum = nums[i] + nums[L] + nums[R];
if(sum == 0){
ans.add(Arrays.asList(nums[i],nums[L],nums[R]));
while (L<R && nums[L] == nums[L+1]) L++; // 去重
while (L<R && nums[R] == nums[R-1]) R--; // 去重
L++;
R--;
}
else if (sum < 0) L++;
else if (sum > 0) R--;
}
}
return ans;
}
}
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode sortList(ListNode head) {
if(head==null){
return head;
}
if(head.next==null){
return head;
}
ListNode aa = new ListNode(0,head);
aa = aa.next;
int len = getlength(head);
int[] arr = new int[len];
for(int i=0;i<len;i++){
arr[i] = aa.val;
aa = aa.next;
}
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length - i - 1; ++j) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
//show();
}
}
}
ListNode min = new ListNode(0,head);
ListNode a = min;
for(int i = 0;i<len;i++){
min.val = arr[i];
if(i==len-1){
min.next = null;
};
min = min.next;
}
return a;
}
public int getlength(ListNode head){
int len = 0;
while(head!=null){
len++;
head = head.next;
}
return len;
}
}