英文:
In a singly linked list how do you shift to the right?
问题
我有一个名为linkedList的类,其中包含头部(head)、尾部(tail)和大小(size)变量。在这个类中,我有一个shift方法,如果方法参数(shiftAmount)中的数字为正数,它会向右移动,如果为负数,它会向左移动。我知道如何向左移动,但不太清楚如何在没有prev指针的情况下向右移动。
public void shift(int shiftAmount) {
if (head == null || head.next == null) {
return;
}
if (shiftAmount < 0) {
shiftAmount = shiftAmount * -1;
for (int i = 0; i < shiftAmount; i++) {
Node temp;
temp = head;
head = head.next;
temp.next = null;
tail.next = temp;
tail = temp;
}
} else {
// 如何向右移动????????
}
}
英文:
I have a class linkedList, which contains the head, tail, and size variables. In this class, I have a shift method, which shifts to the right if the number in the method parameter(shiftAmount) is positive, and to the left, if negative. I understand how to shift to the left but am confused about how to shift right without a prev pointer.
public void shift(int shiftAmount) {
if(head == null || head.next == null) {
return;
}
if(shiftAmount < 0) {
shiftAmount = shiftAmount * -1;
for(int i = 0; i < shiftAmount; i++) {
Node temp;
temp = head;
head = head.next;
temp.next = null;
tail.next = temp;
tail = temp;
}
}
else {
// how do I shift to the right????????
}
}
答案1
得分: 2
如果你所指的 "shift" 是指 "rotate",即将两端的值滚动到列表的开始,那么就足够简单。
例如,假设我们有列表 [1, 3, 5, 7, 9, 11]
。以下是一些 "shift" 的示例:
shift(0): [1, 3, 5, 7, 9, 11]
shift(1): [11, 1, 3, 5, 7, 9]
shift(3): [7, 9, 11, 1, 3, 5]
shift(5): [3, 5, 7, 9, 11, 1]
shift(6): [1, 3, 5, 7, 9, 11]
shift(-1): [3, 5, 7, 9, 11, 1]
正如你所看到的,对于大小为 6,将其右移 6 与右移 0 是相同的,将其右移 5 与左移 1 是相同的。
你可以通过计算模数大小来"归一化"移位值,即 shift % size
。例如,对于大小 6,这将导致一个在 -5 到 +5 范围内的移位值。你可以通过添加大小并再次计算模数来消除左移,即 (shift + size) % size
。综合起来就是:
int normalizedShift = (shift % size + size) % size;
如果归一化的移位值为 0,则停止。完成了。
否则,我们需要获取最后 normalizedShift
个节点并将它们移到前面。
如果你绘制出来,shift(2)
看起来像这样:
之前
头 尾
↓ ↓
1 → 3 → 5 → 7 → 9 → 11
之后
尾 头
↓ ↓
┌→ 1 → 3 → 5 → 7 9 → 11 ─┐
└─────────────────────────────┘
操作如下:
tail.next = head;
// 头 尾
// ↓ ↓
// ┌→ 1 → 3 → 5 → 7 → 9 → 11 ─┐
// └──────────────────────────┘
for (int i = 0; i < size - normalizedShift - 1)
head = head.next;
// 头 尾
// ↓ ↓
// ┌→ 1 → 3 → 5 → 7 → 9 → 11 ─┐
// └──────────────────────────┘
tail = head;
head = head.next;
// 尾 头
// ↓ ↓
// ┌→ 1 → 3 → 5 → 7 → 9 → 11 ─┐
// └────────────────────────────┘
tail.next = null;
// 尾 头
// ↓ ↓
// ┌→ 1 → 3 → 5 → 7 9 → 11 ─┐
// └────────────────────────────┘
总而言之:
public void shift(int shiftAmount) {
int normalizedShift = (shiftAmount % size + size) % size;
if (normalizedShift != 0) {
tail.next = head;
for (int i = 0; i < size - normalizedShift - 1; i++)
head = head.next;
tail = head;
head = head.next;
tail.next = null;
}
}
英文:
If by "shift" you mean "rotate", such that the values at the ends roll over to the beginning, then it's easy enough.
E.g. say we have the list [1, 3, 5, 7, 9, 11]
. Here are some examples of "shifts":
shift(0): [1, 3, 5, 7, 9, 11]
shift(1): [11, 1, 3, 5, 7, 9]
shift(3): [7, 9, 11, 1, 3, 5]
shift(5): [3, 5, 7, 9, 11, 1]
shift(6): [1, 3, 5, 7, 9, 11]
shift(-1): [3, 5, 7, 9, 11, 1]
As you can see, for a size of 6, shifting 6 right is the same as shifting 0, and shifting 5 right is the same as shifting 1 left.
You can normalize the shift value by calculating modulus size, i.e. shift % size
. E.g. for size 6, that will result in a shift value in the range -5 to +5. You can eliminate the left shifts by adding the size and calculating modulus again, i.e. (shift + size) % size
. Combined that means:
int normalizedShift = (shift % size + size) % size;
If the normalized shift is 0, stop. You're done.
Otherwise we need to grab the last normalizedShift
nodes and move them up front.
If you draw it, a shift(2)
looks like this:
BEFORE
head tail
↓ ↓
1 → 3 → 5 → 7 → 9 → 11
AFTER
tail head
↓ ↓
┌→ 1 → 3 → 5 → 7 9 → 11 ─┐
└─────────────────────────────┘
Which is done as follow:
tail.next = head;
// head tail
// ↓ ↓
// ┌→ 1 → 3 → 5 → 7 → 9 → 11 ─┐
// └──────────────────────────┘
for (int i = 0; i < size - normalizedShift - 1)
head = head.next;
// head tail
// ↓ ↓
// ┌→ 1 → 3 → 5 → 7 → 9 → 11 ─┐
// └──────────────────────────┘
tail = head;
head = head.next;
// tail head
// ↓ ↓
// ┌→ 1 → 3 → 5 → 7 → 9 → 11 ─┐
// └────────────────────────────┘
tail.next = null;
// tail head
// ↓ ↓
// ┌→ 1 → 3 → 5 → 7 9 → 11 ─┐
// └────────────────────────────┘
All-in-all:
public void shift(int shiftAmount) {
int normalizedShift = (shiftAmount % size + size) % size;
if (normalizedShift != 0) {
tail.next = head;
for (int i = 0; i < size - normalizedShift - 1; i++)
head = head.next;
tail = head;
head = head.next;
tail.next = null;
}
}
答案2
得分: 0
因为它是单链表,所以无法向右移动。只需将 shiftAmount
右移更改为 size - shiftAmount
左移。
英文:
Since it is a single linked list you can not shift to the right.<br>
Just replace shiftAmount
shift to the right by size - shiftAmount
shift to the left.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论