题目: 给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用 O(1)额外空间并原地修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
代码:
class Solution {
public int removeElement(int[] nums, int val) {
//快慢指针
int slow = 0;
for(int j=0;j<nums.length;j++){
if(nums[j] != val){
nums[slow++] = nums[j];
}
}
return slow;
}
}
class Solution {
public int removeDuplicates(int[] nums) {
//快慢指针
int slow = 1;
for(int i=1;i<nums.length;i++){
if(nums[i] != nums[slow-1]){
nums[slow++] = nums[i];
}
}
return slow ;
}
}
class Solution {
public void moveZeroes(int[] nums) {
//快慢指针
int slow = 0;
for(int i=0;i<nums.length;i++){
if(nums[i] != 0){
nums[slow++] = nums[i];
}
}
for(slow;slow<nums.lenght;slow++){
nums[slow] = 0;
}
}
}
class Solution {
public int[] sortedSquares(int[] nums) {
for(int i=0;i<nums.length;i++){
nums[i] = nums[i] * nums[i];
}
int[] newNums = new int [nums.length];
//双向指针
int left = 0;
int right = nums.length-1;
int i = nums.length-1;
while(left <= right){
if(nums[left] <= nums[right]){
newNums[i--] = nums[right--];
}else{
newNums[i--] = nums[left++]
}
}
return newNums;
}
}
class Solution {
public boolean backspaceCompare(String s, String t) {
//因为#是退格,所以有后向前比较更容易
int i = s.length()-1;
int j = t.length()-1;
//记录退格次数
int countS = 0;
int countT = 0;
while (i>=0 || j>=0){
while (i>=0){
if(s.charAt(i) == '#'){
countS++;
i--;
}else if(countS > 0){
i--;
countS--;
}else {
break;
}
}
while (j>=0){
if(t.charAt(j) == '#'){
countT++;
j--;
}else if(countT > 0) {
j--;
countT--;
}else {
break;
}
}
if(i>=0 && j>=0){
if(s.charAt(i) != t.charAt(j)){
return false;
}
}else if(i>=0 || j>=0){
return false;
}
i--;
j--;
}
return true;
}
}
class Solution {
public ListNode reverseList(ListNode head) {
//双指针法,一个指向前一个节点,一个指向后一个节点,将next反转
ListNode tempNode = new ListNode();
ListNode ansNode = null;
tempNode = head;
while (tempNode != null){
ListNode node = tempNode.next;
tempNode.next = ansNode;
ansNode = tempNode;
tempNode = node;
}
return ansNode;
}
}
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
//快慢指针,找到倒数第n个结点
//快指针先走n个结点,然后快慢指针一起向下遍历,直到快指针指向最后一个结点
ListNode dummyNode = new ListNode();
dummyNode.next = head;
ListNode left = dummyNode;
ListNode right = dummyNode;
while (n >= 0){
right = right.next;
n--;
}
while (right != null){
left = left.next;
right = right.next;
}
left.next = left.next.next;
return dummyNode.next;
}
}
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
//双指针,相交表示节点完全相同,A与B相交最多在倒数第len(headB)处
ListNode tempA = headA;
ListNode tempB = headB;
int n = 0, m = 0;
while (tempA != null){
n++;
tempA = tempA.next;
}
while (tempB != null){
m++;
tempB = tempB.next;
}
tempA = headA;
tempB = headB;
while (n > m){
tempA = tempA.next;
n--;
}
while (m > n){
tempB = tempB.next;
m--;
}
while (tempA != null){
if(tempA == tempB){
return tempA;
}
tempA = tempA.next;
tempB = tempB.next;
}
return null;
}
}
public class Solution {
public ListNode detectCycle(ListNode head) {
//快慢指针,慢指针走一个节点,快指针走2个节点
//若有环则快指针比慢指针多走n个环
ListNode fast = head;
ListNode slow = head;
while (fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
if(slow == fast){
ListNode tempNode1 = head;
ListNode tempNode2 = fast;
while (tempNode1 != tempNode2){
tempNode1 = tempNode1.next;
tempNode2 = tempNode2.next;
}
return tempNode1;
}
}
return null;
}
}
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> ansList = new LinkedList<>();
//利用双指针法,要先固定一个数a,对数组进行排序
//由最左边开始遍历数组,令该遍历的数为a
//在剩余位置使用双向指针确定b,c的值
Arrays.sort(nums);
for (int i = 0; i < nums.length-2; i++) {
if(nums[i] > 0){
break;
}
if(i>0 && nums[i]==nums[i-1]){
continue;
}
int left = i+1;
int right = nums.length-1;
while (left < right){
int sum = nums[i] + nums[left] + nums[right];
if(sum > 0){
right--;
}else if(sum < 0){
left++;
}else {
List<Integer> tempList = Arrays.asList(nums[i],nums[left],nums[right]);
ansList.add(tempList);
while (left < right && nums[left]==nums[left+1]){
left++;
}
while (left < right && nums[right]==nums[right-1]){
right--;
}
left++;
right--;
}
}
}
return ansList;
}
}
题目: 给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):你可以按任意顺序返回答案 。
代码:
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
//这个题与上一题相似,只是这里要固定前两数
List<List<Integer>> ansList = new LinkedList<>();
Arrays.sort(nums);
for (int i = 0; i < nums.length-3; i++) {
if(nums[i]>0 && nums[i]>target){
break;
}
if(i>0 && nums[i]==nums[i-1]){
continue;
}
for (int j = i+1; j < nums.length-2; j++) {
if(j>i+1 && nums[j]==nums[j-1]){
continue;
}
int left = j+1;
int right = nums.length-1;
while (left < right){
long sum = nums[i]+nums[j]+nums[left]+nums[right];
if(sum < target){
left++;
}else if(sum > target){
right--;
}else{
List<Integer> tempList = Arrays.asList(nums[i],nums[j],nums[left],nums[right]);
ansList.add(tempList);
while (left < right && nums[left]==nums[left+1]){
left++;
}
while (left < right && nums[right]==nums[right-1]){
right--;
}
left++;
right--;
}
}
}
}
return ansList;
}
}
class Solution {
public void reverseString(char[] s) {
//交换两个数:a^=b; b^=a; a^=b;
//双指针法反转数组
int left = 0;
int right = s.length-1;
while (left < right){
s[left] ^= s[right];
s[right] ^= s[left];
s[left] ^= s[right];
left++;
right--;
}
}
}
class Solution {
public String reverseWords(String s) {
//去除多余的空格,先去除首尾空格,使用while,双向指针
StringBuilder sb = new StringBuilder();
int left = 0;
int right = s.length()-1;
while (s.charAt(left) == ' '){
left++;
}
while (s.charAt(right) == ' '){
right--;
}
//快慢指针
for (int i = left; i < right+1; i++) {
if(s.charAt(i)==' ' && s.charAt(i-1)==' '){
continue;
}
sb.append(s.charAt(i));
}
//反转整个字符串
int len = sb.length();
char[] charArr = new char[len];
for (int i = 0; i < len; i++) {
charArr[i] = sb.charAt(len-i-1);
}
//将每个单词反转回正常顺序
left = 0;
for (int i = 0; i < len; i++) {
if(charArr[i] == ' '){
reverse(charArr,left,i-1);
left = i+1;
}
if(i == len-1){
reverse(charArr,left,i);
}
}
String str = String.valueOf(charArr);
return str;
}
//双向指针
public void reverse(char[] s,int left,int right) {
while (left < right){
s[left] ^= s[right];
s[right] ^= s[left];
s[left] ^= s[right];
left++;
right--;
}
}
}