Java链表及字符串反转问题集

1、实现单链表反转(递归反转、遍历反转法)

定义一个结点类:

public class Node {

 private int data;  //数据域
 private Node next;    //指针域
  
 
 public Node(int data) {
  super();
  this.data = data;
 }
 public int getData() {
  return data;
 }
 public void setData(int data) {
  this.data = data;
 }
 public Node getNext() {
  return next;
 }
 public void setNext(Node next) {
  this.next = next;
 }
 
}

递归反转:

public static Node reverse(Node head){
  

//如果是空链表或者尾结点
  if (head==null||head.getNext()==null) {
   return head;
  }

//先反转后续结点
  Node reversedHead=reverse(head.getNext());

//当前结点指针指向前一结点
  head.getNext().setNext(head);

//令前一结点的指针域为null
  head.setNext(null);
  return reversedHead;
 }

遍历反转:

public static Node reverse1(Node head){
  
  if (head==null) {
   return head;
  }

//上一结点
  Node pre=head;

//当前结点
  Node cur=head.getNext();

//用于存储下一节点
  Node tem;

//cur==null 即尾结点
  while(cur!=null){

//下一节点存入临时结点
   tem=cur.getNext();

//将当前结点指针指向上一节点
   cur.setNext(pre);

//移动指针
   pre=cur;
   cur=tem;
  }
  head.setNext(null);
  return pre;
 }

2、将一个字符串的部分位置进行反转。如将”abcdefg”反转为”abfedcg”

	@Test
	public void test5(){
		String str = new String("abcdefg");
		String str1 = reverseString(str, 2, 5);
		System.out.println(str1);
		System.out.println(str);

	}
	public String reverseString(String str,int start,int end){
		char[] cs = str.toCharArray();
				
		return reverseArray(cs, start, end);
	}
	public String reverseArray(char[] cs,int start,int end){
		for(int x = start,y = end;x < y;x++,y--){
			char temp = cs[x];
			cs[x] = cs[y];
			cs[y] = temp;
		}
		return new String(cs);
	}
	//另一种方法
	public static String myReserve2(String str,int start,int end){
		String str1 = str.substring(0, start);
		for(int i = end; i > start;i--){
			str1 += str.charAt(i);
		}
		str1 += str.substring(end);
		return str1;
	}

 

3、实现字符串从头到尾的反转

public class StringReverseExe {
	public static void main(String[] args) {
		String str = "helloWorld";
	//方法一:
		String str1 = reverse1(str);
		System.out.println(str1);
		System.out.println("---------------");
	//方法二:
		String str2 = reverse2(str);
		System.out.println(str2);
		System.out.println("---------------");
	
	//方法三:
		String str3 = reverse3(str);
		System.out.println(str3);
		System.out.println("---------------");
		
	}
//方法1:
	public static String reverse1(String str){
		char[] cs  = str.toCharArray();
		for(int i = 0,j = cs.length - 1;i < j;i++,j--){
			char temp = cs[i];
			cs[i] = cs[j];
			cs[j] = temp;
		}
		return new String(cs);
	}
//方法二:
	public static String reverse2(String str){
		StringBuffer sb1 = new StringBuffer(str);
		sb1 = sb1.reverse();
		return sb1.toString();
	}
//方法三:
	public static String reverse3(String str){
		StringBuffer sb = new StringBuffer();
		for(int i = str.length() - 1;i >= 0;i--){
			sb.append(str.charAt(i));
			
		}
		return sb.toString();
	}

}

4、
给定一个单链表,和一个分组数K,每K个结点进行反转,如果最后的结点数不足K个就保持原来的链接顺序不变。

For example, 
  Given this linked list: 1->2->3->4->5 
  For k = 2, you should return: 2->1->4->3->5 
  For k = 3, you should return: 3->2->1->4->5 

解题思路

  用一个指针记录链接好的链表的最后一个结点(tail),用一个指针记录上一次链接好的部分的最后一个结点(head)对未链表的结点在head处进行尾插法,插k个元素,再将head移动到tail处,tail重新记录链表的尾结点,直到所有的元素都进行了操作。如果最后的一组元素不足k个,因为进行过尾插法,所以还要进行还原,对最后的head元素进行尾插法就可以了 。

结点类:

public class ListNode {
    int val;
    ListNode next;

    ListNode(int x) {
        val = x;
    }
}

算法
实现类:

public class Solution {

    public ListNode reverseKGroup(ListNode head, int k) {

        if (k <= 1) {
            return head;
        }

        ListNode root = new ListNode(0);
        // 分组的头一个元素的前驱
        ListNode groupHead = root;
        // 当前要处理的结点
        ListNode curr = head;
        // 处理好的链表的尾结点
        ListNode groupTail = head;
        // 当前要处理的结点的后继
        ListNode next;

        // 对每个组,处理了多少个结点
        int count = 0;


        while (curr != null) {

            // 如果是分组的第一个元素就记录它
            if (count == 0) {
                groupTail = curr;
            }

            // 记录处理的元素个数
            count++;
            // 记录下一个待处理结点
            next = curr.next;
            // 进行尾插法操作
            curr.next = groupHead.next;
            groupHead.next = curr;
            curr = next;

            // 已经处理完了k个结点,分组头的前驱移动到最后一个链接好的结点
            if (count == k) {
                groupHead = groupTail;
                // 计数器归零
                count = 0;
            }
        }


        // 说明结点个数不是k的整数倍,将最后不是整数倍的个元素的结点,
        // 再次使用尾插法进行还原
        if (count != 0) {
            curr = groupHead.next;
            groupHead.next = null;

            while (curr != null) {
                next = curr.next;
                curr.next = groupHead.next;
                groupHead.next = curr;
                curr = next;
            }
        }

        return root.next;
    }
}
6.输入一个英文句子,反转句子中单词的顺序,但单词内字符的顺序不变.
句子中单词以空格隔开,如将"I am a student"转为"student a am I" 
	@Test
	public void test6(){
		String into = "I am a student !";  
        System.out.println(reverse(into));  
	}
	public static String reverse(String into){  
        String[] split = into.split(" ");//对输入的字符串进行分割,返回一个数组  
        StringBuilder sb = new StringBuilder();//由于单线程,StringBuilder效率较高,用于不断地添加字符串  
        for(int i = split.length-1; i>=0; i--){  
            if(i == 0){  
                sb.append(split[i]);//若已是最后一个单词,则不添加空格  
            }else{  
                sb.append(split[i]+" ");  
            }  
        }  
        return sb.toString();//返回一个字符串  
    }  

参考文献:http://blog.csdn.net/derrantcm/article/details/47034983

    原文作者:hdu2012syp
    原文地址: https://blog.csdn.net/qq_27495157/article/details/72925104
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞