剑指offer面试题6——从尾到头打印链表

题目

输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。

示例1

输入:head = [1,3,2]
输出:[2,3,1]

限制:

0 <= 链表长度 <= 10000

C++

方法一:栈实现

#include <iostream>
#include <vector>
#include <stack>
using namespace std;

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};

vector<int> reversePrint(ListNode* head){
    stack<int> Stack;
    ListNode* p = head;
    while (p != NULL) {
        Stack.push(p->val);
        p = p->next;
    }
    vector<int> res;
    while (!Stack.empty()){
        int tmp = Stack.top();
        Stack.pop();
        res.push_back(tmp);        
    }
    return res;
}

int main(){
    ListNode* head = new ListNode(0);
    ListNode* tail = head;
    for (int i=1; i<10; i++) {
        ListNode* node = new ListNode(i);
        tail->next = node;
        tail = tail->next;
    }
    vector<int> res = reversePrint(head);
    for (int i=0; i<res.size(); i++) {
        cout<<res[i]<<" ";
    }
    cout<<endl;
    system("pause");
    return 0;
}

方法二:先计算链表长度 n,然后创建一个长度为 n 的结果数组。最后遍历链表,依次将节点值存放在数组上(从后往前)

vector<int> reversePrint(ListNode* head){
    ListNode* p = head;
    int count = 0;
    while (p != NULL) {
        p = p->next;
        count++;
    }
    vector<int> res(count);
    while (head != NULL) {
        res[--count] = head->val;
        head = head->next;
    }
    return res;
}

Java

方法一:栈实现

package offersix;

import java.util.Arrays;
import java.util.Stack;

public class offersix {
    public static class ListNode{
        int val;
        ListNode next;
        ListNode(int x) { val = x;}
    }

    public static int[] reversePrint(ListNode head){
        Stack<Integer> stack = new Stack<>();
        while (head != null) {
            stack.push(head.val);
            head = head.next;
        }
        int []res = new int[stack.size()];
        int i=0;
        while (!stack.empty()) {
            res[i++] = stack.pop();
        }
        return res;
    }

    public static void main(String[] args) {
        ListNode head = new ListNode(0);
        ListNode rt = head;
        for(int i = 1; i < 10; i++) {
            ListNode node = new ListNode(i);
            rt.next = node;
            rt = rt.next;
        }
        int [] res = reversePrint(head);
        System.out.println(Arrays.toString(res));
    }

}

方法二:先计算链表长度 n,然后创建一个长度为 n 的结果数组。最后遍历链表,依次将节点值存放在数组上(从后往前)

public static int[] reversePrint(ListNode head){
        int count = 0;
        ListNode tmp = head;
        while (tmp != null) {
            tmp = tmp.next;
            count++;
        }
        int []res = new int[count];
        int j = count - 1;
        while (head != null) {
            res[j] = head.val;
            head = head.next;
            j--;
        }
        return res;
    }

Python

class ListNode:
    def __init__(self, val):
        self.val = val
        self.next = None


def reversePrint(head):
    lst = []
    tmp = head 
    while tmp != None:
        lst.append(tmp.val)
        tmp = tmp.next
    n = len(lst)
    for i in range(n//2+1):
        lst[i], lst[n-i-1] = lst[n-i-1], lst[i]
    return lst
    


def printListNode(head):
    nums = []
    while head != None:
        nums.append(head.val)
        head = head.next
    print(nums)

head = ListNode(0)
tail = head
for i in range(1, 10):
    node = ListNode(i)
    tail.next = node
    tail = tail.next

printListNode(head)
res = reversePrint(head)
print(res)

Go

方法一:用栈记录

package main

import "fmt"

type ListNode struct {
	Val  int
	Next *ListNode
}

func reversePrint(head *ListNode) []int {
	res := []int{}
	for head != nil {
		res = append([]int{head.Val}, res...)
		head = head.Next
	}
	return res
}

func ListNodePrint(head *ListNode) {
	for head != nil {
		fmt.Println(*head)
		head = head.Next
	}
}

func main() {
	var head = new(ListNode)
	head.Val = 0
	var tail *ListNode
	tail = head
	// 头插法
	/*
	for i := 1; i < 10; i++ {
		var node = ListNode{Val: i}
		node.Next = tail
		tail = &node
	}
	*/
	// 尾插法
	for i := 1; i < 10; i++ {
		var node = ListNode{Val: i}
		(*tail).Next = &node
		tail = &node
	}
	ListNodePrint(head)
	res := reversePrint(head)
	fmt.Println(res)
}

方法二:先计算链表长度 n,然后创建一个长度为 n 的结果数组。最后遍历链表,依次将节点值存放在数组上(从后往前)

func reversePrint(head *ListNode) []int {
	cur := head
	n := 0
	for head != nil {
		head = head.Next
		n++
	}
	nums := make([]int, n)
	for {
		if cur == nil {
			break
		}
		nums[n-1] = cur.Val
		cur = cur.Next
		n--
	}
	return nums
}

方法三:反转数组

func reversePrint(head *ListNode) []int {
    var arr []int

	for head != nil {
		arr = append(arr, head.Val)
		head = head.Next
	}

	if len(arr) == 0 {
		return nil
	}

	length := len(arr)
	for i := 0; i < length / 2; i++ {
		temp := arr[i]
		arr[i] = arr[length - i - 1]
		arr[length - i - 1] = temp
	}

	return arr
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值