Given the head
of a singly linked list, return true
if it is a palindrome or false
otherwise.
Example 1:
Input: head = [1,2,2,1] Output: true
Example 2:
Input: head = [1,2] Output: false
Constraints:
[1, 105]
.0 <= Node.val <= 9
Follow up: Could you do it in O(n)
time and O(1)
space?
program palindrome_list
implicit none
type :: node
integer :: val
type(node), pointer :: next => null()
end type
type(node), pointer :: head
logical :: result
call test_example1()
call test_example2()
contains
subroutine test_example1()
type(node), pointer :: curr
allocate(curr)
curr%val = 1
curr%next => curr
allocate(curr%next)
curr%next%val = 2
curr%next%next => curr
allocate(curr%next%next)
curr%next%next%val = 2
curr%next%next%next => curr
allocate(curr%next%next%next)
curr%next%next%next%val = 1
curr%next%next%next%next => null()
result = is_palindrome(head)
write (*, '(A, L1)') 'Example 1: ', result
end subroutine
subroutine test_example2()
type(node), pointer :: curr
allocate(curr)
curr%val = 1
curr%next => curr
allocate(curr%next)
curr%next%val = 2
curr%next%next => null()
result = is_palindrome(head)
write (*, '(A, L1)') 'Example 2: ', result
end subroutine
function is_palindrome(head) result(result_)
type(node), pointer, intent(in) :: head
type(node), pointer :: slow, fast
logical :: result_
slow => head
fast => head
do while (associated(fast))
if (.not. associated(fast%next)) exit
fast => fast%next%next
slow => slow%next
end do
result_ = .true.
do while (associated(slow))
if (slow%val /= fast%val) then
result_ = .false.
exit
end if
slow => slow%next
fast => fast%next
end do
end function
end program
Program received signal SIGSEGV: Segmentation fault - invalid memory reference. Backtrace for this error: #0 0x7dbf9f648960 in ??? #1 0x7dbf9f647ac5 in ??? #2 0x7dbf9f43e51f in ??? #3 0x56473cb901d6 in is_palindrome.0 #4 0x56473cb9066f in test_example1.2 #5 0x56473cb90263 in MAIN__ #6 0x56473cb9075a in main
module palindrome_list
implicit none
type :: node
integer :: val
type(node), pointer :: next => null()
end type node
interface
function is_palindrome(head) result(is_palindrome)
type(node), pointer, intent(in) :: head
logical :: is_palindrome
end function is_palindrome
end interface
contains
function is_palindrome(head) result(is_palindrome)
type(node), pointer, intent(in) :: head
type(node), pointer :: slow, fast
integer :: length, mid, i
logical :: is_palindrome
! Find the length of the list
length = 0
do
length = length + 1
if (.not. associated(head%next)) exit
head => head%next
end do
! Find the middle of the list
mid = length / 2 + 1
! Reverse the second half of the list
slow => head
do i = 1, mid - 1
fast => slow%next
slow%next => fast%next
fast%next => slow
end do
! Check if the first and second halves are the same
is_palindrome = .true.
do i = 1, mid
if (head%val /= slow%val) then
is_palindrome = .false.
exit
end if
head => head%next
slow => slow%next
end do
end function is_palindrome
end module palindrome_list
program test
use palindrome_list
implicit none
! Examples
type(node), pointer :: head
head => null()
call add_node(head, 1)
call add_node(head, 2)
call add_node(head, 2)
call add_node(head, 1)
write (*,*) is_palindrome(head)
head => null()
call add_node(head, 1)
call add_node(head, 2)
call add_node(head, 3)
write (*,*) is_palindrome(head)
contains
subroutine add_node(head, val)
type(node), pointer, intent(inout) :: head
integer, intent(in) :: val
type(node), pointer :: new_node
allocate(new_node)
new_node%val = val
new_node%next => head
head => new_node
end subroutine add_node
end program test
temp.f95:11:54: 11 | function is_palindrome(head) result(is_palindrome) | 1 Error: RESULT variable at (1) must be different than function name temp.f95:12:47: 12 | type(node), pointer, intent(in) :: head | 1 Error: Unexpected data declaration statement in INTERFACE block at (1) temp.f95:13:32: 13 | logical :: is_palindrome | 1 Error: Unexpected data declaration statement in INTERFACE block at (1) temp.f95:14:7: 14 | end function is_palindrome | 1 Error: Expecting END INTERFACE statement at (1) temp.f95:19:50: 19 | function is_palindrome(head) result(is_palindrome) | 1 Error: RESULT variable at (1) must be different than function name temp.f95:20:43: 20 | type(node), pointer, intent(in) :: head | 1 Error: Unexpected data declaration statement in CONTAINS section at (1) temp.f95:21:37: 21 | type(node), pointer :: slow, fast | 1 Error: Unexpected data declaration statement in CONTAINS section at (1) temp.f95:22:29: 22 | integer :: length, mid, i | 1 Error: Unexpected data declaration statement in CONTAINS section at (1) temp.f95:23:28: 23 | logical :: is_palindrome | 1 Error: Symbol ‘is_palindrome’ at (1) has already been host associated temp.f95:26:14: 26 | length = 0 | 1 Error: Unexpected assignment statement in CONTAINS section at (1) temp.f95:27:6: 27 | do | 1 Error: Unexpected DO statement in CONTAINS section at (1) temp.f95:28:27: 28 | length = length + 1 | 1 Error: Unexpected assignment statement in CONTAINS section at (1) temp.f95:29:35: 29 | if (.not. associated(head%next)) exit | 1 Error: Symbol ‘head’ at (1) has no IMPLICIT type temp.f95:30:22: 30 | head => head%next | 1 Error: Symbol ‘head’ at (1) has no IMPLICIT type temp.f95:31:7: 31 | end do | 1 Error: Expecting END MODULE statement at (1) temp.f95:34:24: 34 | mid = length / 2 + 1 | 1 Error: Unexpected assignment statement in CONTAINS section at (1) temp.f95:37:16: 37 | slow => head | 1 Error: Unexpected pointer assignment statement in CONTAINS section at (1) temp.f95:38:21: 38 | do i = 1, mid - 1 | 1 Error: Unexpected DO statement in CONTAINS section at (1) temp.f95:39:22: 39 | fast => slow%next | 1 Error: Symbol ‘slow’ at (1) has no IMPLICIT type temp.f95:40:14: 40 | slow%next => fast%next | 1 Error: Symbol ‘slow’ at (1) has no IMPLICIT type temp.f95:41:14: 41 | fast%next => slow | 1 Error: Symbol ‘fast’ at (1) has no IMPLICIT type temp.f95:42:7: 42 | end do | 1 Error: Expecting END MODULE statement at (1) temp.f95:45:18: 45 | is_palindrome = .true. | 1 Error: Symbol ‘is_palindrome’ at (1) has already been host associated temp.f95:46:17: 46 | do i = 1, mid | 1 Error: Unexpected DO statement in CONTAINS section at (1) temp.f95:47:18: 47 | if (head%val /= slow%val) then | 1 Error: Symbol ‘head’ at (1) has no IMPLICIT type temp.f95:48:26: 48 | is_palindrome = .false. | 1 Error: Symbol ‘is_palindrome’ at (1) has already been host associated temp.f95:49:16: 49 | exit | 1 Error: EXIT statement at (1) is not within a construct temp.f95:50:11: 50 | end if | 1 Error: Expecting END MODULE statement at (1) temp.f95:51:22: 51 | head => head%next | 1 Error: Symbol ‘head’ at (1) has no IMPLICIT type temp.f95:52:22: 52 | slow => slow%next | 1 Error: Symbol ‘slow’ at (1) has no IMPLICIT type temp.f95:53:7: 53 | end do | 1 Error: Expecting END MODULE statement at (1) temp.f95:55:3: 55 | end function is_palindrome | 1 Error: Expecting END MODULE statement at (1) temp.f95:60:9: 60 | use palindrome_list | 1 Fatal Error: Cannot open module file ‘palindrome_list.mod’ for reading at (1): No such file or directory compilation terminated.
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def isPalindrome(head):
if not head or not head.next:
return True
fast, slow, prev = head, head, None
while fast and fast.next:
fast = fast.next.next
temp = slow.next
slow.next = prev
prev = slow
slow = temp
if fast:
slow = slow.next
while prev and prev.val == slow.val:
prev = prev.next
slow = slow.next
return prev == None
The function uses the slow and fast pointers approach to find the middle of the linked list. It simultaneously reverses the first half of the linked list. At the end of this process, slow will be at the middle and prev will be the reversed first half of the list. If the list has an odd length, slow moves one step forward (skipping the middle element). Finally, we compare the elements of the reversed first half (using prev) and the rest of the list (starting from slow). If they match, it means the list is a palindrome.
class ListNode {
public:
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
bool isPalindrome(ListNode* head) {
if (!head || !head->next) return true;
ListNode *fast = head, *slow = head, *prev = NULL;
while (fast && fast->next) {
fast = fast->next->next;
ListNode *temp = slow->next;
slow->next = prev;
prev = slow;
slow = temp;
}
if (fast) slow = slow->next;
while (prev && prev->val == slow->val) {
prev = prev->next;
slow = slow->next;
}
return prev == NULL;
}
The function uses the slow and fast pointers approach to find the middle of the linked list. It simultaneously reverses the first half of the linked list. At the end of this process, slow will be at the middle and prev will be the reversed first half of the list. If the list has an odd length, slow moves one step forward (skipping the middle element). Finally, we compare the elements of the reversed first half (using prev) and the rest of the list (starting from slow). If they match, it means the list is a palindrome.