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