和数组不同的是,链表并不需要一块连续的内存空间,它可以通过指针将一组零散的内存块串联起来使用。链表的基本操作是最考验逻辑思维能力的,尤其需要注意:
| 刷题清单 | 备注 |
|---|---|
| 21. 合并两个有序链表 | |
| 203. 移除链表元素 | |
| 206.反转链表 | |
| 707.设计链表 | |
| *25.K 个一组翻转链表 | 保护结点 |
| 24. 两两交换链表中的节点 | |
| 141.环形链表 | 快慢指针|哈希表 |
| *142.环形链表 II | 快慢指针|哈希表|数学 |
| *19. 删除链表的倒数第 N 个结点 | 快慢指针 |
对序列\(A\)中每一个数\(A_i\),求在\(A_i\)前的数与\(A_i\)的最小差值,以及对应下标(若最小差值对应下标不唯一,则返回最小下标)。例如,输入1, 5, 3, 4, 2。
一个可能的想法是,对前\(i\)个数维护一个有序集合,二分查找\(A_i\)的前驱与后继,比较差值,返回最小差值与对应下标:
1, 5:添加5,前驱为1,后继为\,最小差值为4,对应下标1
1,3,5:添加3,前驱为1,后继为5,最小差值为2,对应下标1
1,3,4,5:添加4,前驱为3,后继为5,最小差值为1,对应下标2
1,2,3,4,5:添加2,前驱为1,后继为3,最小差值为1,对应下标1
import java.io.*;
import java.util.Map;
import java.util.TreeMap;
public class Main {
public static void main(String[] args) throws Exception {
StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
BufferedWriter br = new BufferedWriter(new OutputStreamWriter(System.out));
st.nextToken();
int n = (int) st.nval;
// 平衡树
TreeMap<Integer, Integer> map = new TreeMap<>();
for (int i = 1; i <= n; i++) {
st.nextToken();
int val = (int) st.nval;
// 添加关键字和对应的值,即数值与下标
map.put(val, i);
if (i != 1) {
// 返回大于等于 key 的最小元素
Map.Entry<Integer, Integer> up = map.ceilingEntry(val + 1);
// 返回小于等于 key 的最大元素
Map.Entry<Integer, Integer> down = map.floorEntry(val - 1);
int res = Integer.MAX_VALUE, pos = -1;
if (down != null) {
res = val - down.getKey();
pos = down.getValue();
}
if (up != null && up.getKey() - val < res) {
res = up.getKey() - val;
pos = up.getValue();
}
br.write(res + " " + pos);
br.newLine();
}
}
br.flush();
}
}
顺序添加元素可行,那倒序删除呢?依然是维护一个有序序列:
图1.2.1 样例及实现
数组:按下标索引,记录每个下标对应的链表结点,便于快速访问双链表:按值排序,倒序考虑每个下标,前后比较,删除相应结点注意,虽然Java内置LinkedList,但是容器接口没有暴露具体的实现方法,也无法获取前驱后继。
所以,双链表需要自己手动实现。
import java.io.*;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;
class Main {
static int n;
// 双链表,便于删除和查询前驱后继
static Node head;
static Node tail;
// 数组,便于根据索引快速访问结点
public static void main(String[] args) throws IOException {
StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
st.nextToken();
n = (int) st.nval;
Node[] pile;
pile = new Node[n + 1];
// 虚拟/保护结点
head = new Node(-1, -1);
tail = new Node(-1, -1);
// 空双链表初始化
head.next = tail;
tail.prev = head;
// 按值排序
Node[] nodes = new Node[n];
for (int i = 1; i <= n; i++) {
st.nextToken();
Node node = new Node((int) st.nval, i);
nodes[i - 1] = node;
pile[i] = node;
}
Arrays.sort(nodes, (o1, o2) -> o1.val - o2.val);
for (int i = n - 1; i >= 0; i--) {
// 头插
Node node = nodes[i];
node.next = head.next;
node.prev = head;
head.next.prev = node;
head.next = node;
}
Deque<String> stack = new ArrayDeque<>();
for (int i = n; i >= 2; i--) {
Node node = pile[i];
int pos = -1;
int diff = Integer.MAX_VALUE;
// 优先考虑前驱
if (node.prev != head) {
diff = node.val - node.prev.val;
pos = node.prev.index;
}
if (node.next != tail && node.next.val - node.val < diff) {
diff = node.next.val - node.val;
pos = node.next.index;
}
stack.push(diff + " " + pos);
// 删除结点
node.prev.next = node.next;
node.next.prev = node.prev;
}
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
while (!stack.isEmpty()) {
bw.write(stack.pop());
bw.newLine();
}
bw.flush();
bw.close();
}
static class Node {
int val;
int index;
Node prev;
Node next;
public Node(int val, int index) {
this.val = val;
this.index = index;
}
}
}
我得到NameError:undefinedlocalvariableormethodwithruby2.1.2正如在thisquestion中观察到的那样,表达式如:barifbar=true引发未定义的局部变量错误(前提是bar之前未定义),因为bar在分配之前被解析器读取。而且我相信以前用这个表达式没有什么区别:barifbar=false两者之间的区别在于主体是否被求值,但如果遇到未定义的局部变量会在求值条件之前立即引发错误,那应该无关紧要。但是当我在Ruby2.1.2上运行第二个代码时,它没有引发错误。以前也是这样吗?如果是这样,那么解析讨论的内容是什么?如果没有,Rub
前文,我们实现了认识了链表这一结构,并实现了无头单向非循环链表,接下来我们实现另一种常用的链表结构,带头双向循环链表。如有仍不了解单向链表的,请看这一篇文章(7条消息)【数据结构和算法】认识线性表中的链表,并实现单向链表_小王学代码的博客-CSDN博客目录前言一、带头双向循环链表是什么?二、实现带头双向循环链表1.结构体和要实现函数2.初始化和打印链表3.头插和尾插4.头删和尾删5.查找和返回结点个数6.在pos位置之前插入结点7.删除指定pos结点8.摧毁链表三、完整代码1.DSLinkList.h2.DSLinkList.c3.test.c总结前言带头双向循环链表,是链表中最为复杂的一种结
我认为ruby或rails中有一种方法可以执行此操作,但我不记得在哪里可以找到它或如何搜索它,所以我希望stackoverflow的集体智慧可能有所帮助。我不介意编写一个方法来执行此操作,但我确信有人有更好的解决方案。 最佳答案 number_to_human(1200,:format=>'%n%u',:units=>{:thousand=>'K'})#1200=>1.2K 关于ruby-on-rails-在ruby/rails中将1200转换为1.2K,我们在StackOver
我在网上查了几个Ruby教程,他们似乎什么都用数组。那么如何在Ruby中实现以下数据结构呢?堆栈队列链表map组 最佳答案 (从评论中移出)好吧,通过限制堆栈或队列方法(push、pop、shift、unshift),数组可以是堆栈或队列。使用push/pop提供LIFO(后进先出)行为(堆栈),而使用push/shift或unshift/pop提供FIFO行为(队列)。map是hashes,和一个Set类已经存在。您可以使用类实现链表,但数组将使用标准数组方法提供类似于链表的行为。 关
我有一个开源项目,正在升级以使用angular1.2rc3。本质上它处理表单按钮上的promise。在这个plnkrhttp://plnkr.co/edit/vQd97YEpYO20YHSuHnN0?p=preview您应该能够单击右侧的“保存”并在控制台中看到“已单击”,因为它应该在指令中执行此代码:scope[functionName]=function(){console.log('clicked');//ifit'salreadybusy,don'tacceptanewclickif(scope.busy===true){return;}scope.busy=true;varr
我是JS的新手,组织数据的概念让我有些困惑,我试图从特定的数组格式中获取数据(因为这是我必须使用的格式)并将其输出为另一种特定的JSON格式。这是给D3sankey模块传递数据https://github.com/d3/d3-plugins/blob/master/sankey/sankey.js我不知道如何将节点的索引添加到链接中,而不是名称。真的,我完全迷失了它!我在这里做了一个fiddle:https://jsfiddle.net/adamdavi3s/kw3jtzx4/下面是所需数据和输出的示例vardata=[{"source":"Agricultural'waste'","
文章目录1.题目描述2.解题思路方法1:方法2:1.题目描述题目链接:力扣21,合并两个有序链表将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。2.解题思路方法1:首先我们能够想到的就是遍历一遍数组,判断两个结点的大小,将数值小的结点放在前面,数值大的不断尾插在后面。是不是听着挺简单的?具体实现:我们可以创建两个空指针,head用来存放链表的头结点,tail用来遍历两条链表,将两条链表链接起来。当某个链表为空时,我们可以直接返回另一条链表当两个链表都不为空时,我们可以不断比较两条链表的大小,当head和tail为空时,我们将较小的结点同时赋给head
所以我在JS中玩弄链表并提出了以下问题:比方说,我们有一个数组和一个链表,它们都有5000个元素。我们想在索引10处插入新元素。数组方式非常简单。我们在给定索引处插入新元素,并将其余元素向前移动一个索引。所以我尝试用链表来做这件事,并以下面的方式结束它:从NicholasZakas获取链表的实现并添加附加方法addOnPosition(data,index)。最后是代码:functionLinkedList(){this._head=null;this._length=0;}LinkedList.prototype={constructor:LinkedList,add:functio
在thisquestion中使用随机orderBy排序技术在AngularJS1.1中工作正常。varmyApp=angular.module('myApp',[]);functionMyCtrl($scope){$scope.list=['a','b','c','d','e','f','g'];$scope.random=function(){return0.5-Math.random();}}但是,在1.2中,它会将infdig错误放入控制台,并且需要更长的时间来返回排序结果:http://jsfiddle.net/mblase75/jVs27/控制台中的错误如下所示:Error:
我有一个返回国家列表的AJAX函数。它工作正常。我的问题是,想要在已经是HTML且为空的选择框中加载国家/地区意味着其中没有选项值。我想知道如何使用moo工具1.2创建一个新的选项元素并注入(inject)到选择框中我使用了下面的代码,但它在IE中不起作用。varNewOption=newOption("SelectSubCategory",'0');NewOption.inject($('nSub_nIndustryID'))谢谢阿维纳什 最佳答案 没有必要创建变量,除非您稍后要使用它。newElement('option',{'