三十六、题目
设计一个支持push,pop,top和在恒定时间内检索最小元素的堆栈。
push(x) - 将元素x推入堆栈。
pop() - 删除堆栈顶部的元素。
top() - 获取顶部元素。
getMin() - 检索堆栈中的最小元素。
思路:
使用链表存储元素,每一次添加元素就是直接在链表的尾部添加,在添加的过程中判断这个元素是不是最小,将这个最小的元素存储到变量min中,返回栈顶元素其实就是返回链表尾部的元素,返回最小元素就是返回min,难点应该在弹栈操作,如果弹出的元素比最小值大,那么就直接弹栈,如果弹栈的元素比最小值小或者等于最小值,那么在弹出这个元素的时候,就要重新去找整个栈或者说整个链表中的最小元素,作为min函数的结果。
Example:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> Returns -3.
minStack.pop();
minStack.top(); --> Returns 0.
minStack.getMin(); --> Returns -2.
package cn.hnu.leetcode.easy;
import java.util.LinkedList;
public class _155_MinStack {
LinkedList list;
int min;
/**
* 初始化栈,底层用链表实现,并确定最小值就是Integer中的最大值
*/
public _155_MinStack() {
list = new LinkedList();
min = Integer.MAX_VALUE;
}
/**
* 往栈中添加元素
* @param x
*/
//往栈中添加元素,边添加边确定当前这个数是不是整个链表元素中最小的
public void push(int x) {
list.add(x);
if(x < min){
min = x;
}
}
/**
* 弹栈操作,如果最后一个元素比最小的元素大,直接弹栈,如果不大于最小的元素,那么移除之后
* 要重新考虑整个链表中最小的那个元素是哪个
*/
public void pop() {
//获取链表的最后一个元素
int last = list.getLast();
//如果最后一个元素比再添加时已经确定的最小元素大,那么没关系,直接移除最后一个元素
if(last>min){
list.removeLast();
//如果移除的最后一个元素小于等于最小值,其实也就只可能等于
//那么需要重新找到最小值
}else{
list.removeLast();
min = Integer.MAX_VALUE;
for(int i = 0;i
三十七、题目
给定两个链表,这两个链表可能存在交点也可能没有,设计程序找到这个公共节点,如果没有返回0
注意:
如果两个链表没有交点,则返回null。
函数返回后,链表必须保留其原始结构。
在给定的链表中没有任何循环。
代码的时间复杂度最好在O(n),空间复杂度是O(1)内存。
思路:
假设链表A不包含公共部分的长度是a,链表B不包含公共部分的长度是b,公共长度是c,如果链表存在交点那么必定满足a+c + b = b+c +a,所有就是循环的过程,当A_point指向A链表尾的时候,让它指向链表B的头;当B_point指向B链表的尾部时,让它指向A链表的头,如此总能找到公共节点在哪里。当然没有交点时c=0,上面也是成立的。
For example, the following two linked lists:
begin to intersect at node c1.
Example 1:
Input: intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
Output: Reference of the node with value = 8
Input Explanation: The intersected node's value is 8 (note that this must not be 0 if the two lists intersect). From the head of A, it reads as [4,1,8,4,5]. From the head of B, it reads as [5,0,1,8,4,5]. There are 2 nodes before the intersected node in A; There are 3 nodes before the intersected node in B.
Example 2:
Input: intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
Output: Reference of the node with value = 2
Input Explanation: The intersected node's value is 2 (note that this must not be 0 if the two lists intersect). From the head of A, it reads as [0,9,1,2,4]. From the head of B, it reads as [3,2,4]. There are 3 nodes before the intersected node in A; There are 1 node before the intersected node in B.
Example 3:
Input: intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
Output: null
Input Explanation: From the head of A, it reads as [2,6,4]. From the head of B, it reads as [1,5]. Since the two lists do not intersect, intersectVal must be 0, while skipA and skipB can be arbitrary values.
Explanation: The two lists do not intersect, so return null.
package cn.hnu.leetcode.easy;
import cn.hnu.leetcode.easy.use_Class.ListNode;
public class _160_GetIntersectionNode {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
//A_point开始指向A链表的头
ListNode A_point = headA;
//B_point开始指向B链表的头
ListNode B_point = headB;
//如果两个指针不相遇,就一直遍历
while(A_point!=B_point){
//当A_point指向A链表的尾时,让它指向B链表的头
if(A_point==null){
A_point = headB;
//否则指针后移
}else{
A_point = A_point.next;
}
//当B_point指向B链表的尾时,让它指向A链表的头
if(B_point==null){
B_point = headA;
//否则指针后移
}else{
B_point = B_point.next;
}
}
return A_point;
}
}
三十八、题目
给定已按升序排序的整数数组,找到两个数字,使它们相加得到特定的目标数。
函数twoSum应返回两个数字的索引,以便它们加起来到目标,其中index1必须小于index2。
注意:
返回的答案(index1和index2)不是从零开始的。
您可以假设每个输入只有一个解决方案,并且您可能不会两次使用相同的元素。
思路:
看见排好序的数组,然后又是查找,应当优先想到二分法的思想,既然数字排好序,那么找两个数的索引,那就是两个指针分别指向头和尾,然后就是这两个索引对应的值相加如果大于目标数,那么范围大了,应该让尾指针前移,否则头指针后移,不能一半一半的缩小,鬼知道尾指针到mid和mid到尾指针之间是否存在要找的数字。但是最终返回的索引别忘了+1,因为得到的结果索引不是从零开始的。
Example:
Input: numbers = [2,7,11,15], target = 9
Output: [1,2]
Explanation: The sum of 2 and 7 is 9. Therefore index1 = 1, index2 = 2.
package cn.hnu.leetcode.easy;
public class _167_TwoSum {
public int[] twoSum(int[] numbers, int target) {
//定义头指针
int low = 0;
//定义尾指针
int high = numbers.length-1;
//设置最终结果集
int[] res = new int[2];
//遍历找结果
while(lowtarget){
high--;
}else if(numbers[low]+numbers[high]
三十九、题目
给定正整数,返回Excel工作表中显示的相应列标题
思路:
其实就是将数字用A-Z表示。就是26进制,把一个整数表示成26进制的数
For example:
1 -> A
2 -> B
3 -> C
...
26 -> Z
27 -> AA
28 -> AB
...
Example 1:
Input: 1
Output: "A"
Example 2:
Input: 28
Output: "AB"
Example 3:
Input: 701
Output: "ZY"
package cn.hnu.leetcode.easy;
public class _168_ConvertToTitle {
public String convertToTitle(int n) {
String str = "";
int temp = 0;
//其实就是十进制转二十六进制的问题
while(n>0){
//因为n是从1开始,1代表"A"
//比如把n=27代入下面
temp = (n-1) % 26;
str = (char)('A'+temp)+str;
n = (n-1) / 26;
}
return str;
}
}
四十、题目
给定大小为n的数组,找到出现次数最多的那个元素。该元素是出现超过⌊n /2⌋倍次的元素。
假设该数组非空,并且该元素始终存在于数组中。
思路
提供两种做法
方法一:将
Example 1:
Input: [3,2,3]
Output: 3
Example 2:
Input: [2,2,1,1,1,2,2]
Output: 2