328、难度中等:
要求:
1、使用原地算法完成。算法的空间复杂度应为 O(1),时间复杂度应为 O(nodes),nodes 为节点总数。
2、结果链表中第一部分应该为奇数节点总和,然后是偶数节点总和。
3、结果链表保持原有节点顺序。
方法一:原创:分离节点后合并
思路:
如果题传链表为空或者只有一个节点那就返回首节点。
head节点作为创造出奇数链表的首节点,ans = head 保留首节点。
ou = head.next 作为创造出偶数链表的首节点,oushou = ou 保留首节点。
然后开始循环,为防止末尾节点 null 属于奇数节点的范畴(否则结果链表会成为:奇数->null->偶数),所以我们让循环结束条件为head.next != null && ou.next != null(当前节点下一项不为null)
开始循环,我们让奇数.next指向偶数.next,再更新奇数 = 奇数.next;
再让偶数.next指向奇数.next,再更新偶数 = 偶数.next;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9c8F0uOY-1635406907528)(328. 奇偶链表.assets/image-20211027094320330.png)]
循环结束时,由于循环结束条件为下一个节点不为null,所以结束时head和ou中有一项.next = null,但是 head 和 ou 一直相邻并且ou必然在 head 后(while循环内的代码执行顺序导致该情况),所以结束时只能是 ou.nenxt = null,head.next = ou**
所以在循环结束后我们只要让head.next = oushou,就能让奇偶链表连起来。
class Solution {
public ListNode oddEvenList(ListNode head) {
if(head == null || head.next == null){
return head;
}
ListNode ou = head.next;
ListNode oushou = ou;
ListNode ans = head;
while(head.next != null && ou.next != null){
head.next = ou.next;
head = head.next;
ou.next = head.next;
ou = ou.next;
}
head.next = oushou;
return ans;
}
}
707、难度中等:通过率32%
要求:不要使用内置的 LinkedList 库
思路:照着下方代码读一遍即可。
// 作为节点
public class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
// 链表
class MyLinkedList {
int size; // 长度
ListNode head; // 头结点
public MyLinkedList() {
size = 0;
head = new ListNode(0); // 给头结点赋值为 0
}
/** Get the value of the index-th node in the linked list. If the index is invalid, return -1. */
public int get(int index) {
// if index is invalid
if (index < 0 || index >= size) return -1;
ListNode curr = head;
// index steps needed
// to move from sentinel node to wanted index
for(int i = 0; i < index + 1; ++i) curr = curr.next;
return curr.val;
}
/** Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list. */
public void addAtHead(int val) {
addAtIndex(0, val);
}
/** Append a node of value val to the last element of the linked list. */
public void addAtTail(int val) {
addAtIndex(size, val);
}
/** Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted. */
public void addAtIndex(int index, int val) {
// 当index溢出就什么也不做
if (index > size) return;
// 根据题意当index小于 0 时就将其判定为 0
if (index < 0) index = 0;
++size;
// pred是index的前一项
ListNode pred = head;
for(int i = 0; i < index; ++i) pred = pred.next;
// toAdd是要插入的节点
ListNode toAdd = new ListNode(val);
// 实现结果:pred -> toAdd -> index
toAdd.next = pred.next;
pred.next = toAdd;
}
/** Delete the index-th node in the linked list, if the index is valid. */
public void deleteAtIndex(int index) {
// if the index is invalid, do nothing
if (index < 0 || index >= size) return;
size--;
// find predecessor of the node to be deleted
ListNode pred = head;
for(int i = 0; i < index; ++i) pred = pred.next;
// delete pred.next
pred.next = pred.next.next;
}
}