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????????
}
}
If by "shift" you mean "rotate", such that the values at the ends roll over to the beginning, then it's easy enough.
Eg 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, ie shift % size
. Eg 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, ie (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;
}
}
Since it is a single linked list you can not shift to the right.
Just replace shiftAmount
shift to the right by size - shiftAmount
shift to the left.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.