18

package scalaCode

/**
  * Created by zp on 2017/7/13.
  */
package leetcode

import scala.collection.mutable.ListBuffer
import scala.util.control.Breaks

object FourSum {

  def twoSumForFourSum(nums: Array[Int], target: Int, start: Int, res: ListBuffer[ListBuffer[Int]], z1: Int, z2: Int): Unit = {
    val high = nums.size - 1
    if (start >= high) {
      return None
    }

    if (2 * nums(start) > target || 2 * nums(high) < target){
      return None
    }

    var i = start
    var j = high
    var sum = 0
    var x = 0
    while (i < j){
      sum = nums(i) + nums(j)
      if (sum == target){
        val tmp = new ListBuffer[Int]
        tmp += (z1, z2, nums(i), nums(j))
        res += tmp

        x = nums(i)
        while (i < j && nums(i) == x) {i += 1}
        x = nums(j)
        while (i < j && nums(j) == x) {j -= 1}
      }

      if (sum < target){
        i += 1
      }
      if (sum > target) {
        j -= 1
      }
    }
  }

  def threeSumFourSum(nums: Array[Int], target: Int, start : Int, res: ListBuffer[ListBuffer[Int]], z1: Int) {
    val high = nums.size - 1
    val max = nums(high)

    //异常情况
    if (3 * nums(start) > target || 3 * max < target){
      return
    }

    var first = new Breaks
    var second = new Breaks
    var thrid = new Breaks
    var loop = new Breaks

    var z = 0
    loop.breakable{
      for (i <- start to high){
        z = nums(i)
        first.breakable{
          if (i > start && z == nums(i - 1)){
            first.break()
          }
        }

        second.breakable{
          if (z + 2 * max < target) {
            second.break()
          }
        }

        thrid.breakable{
          if (3 * z > target){
            thrid.break()
          }
        }

        if ( 3 * z == target) {
          if (i + 2 <= high && nums(i + 2) == z){
            val tmp = new ListBuffer[Int]
            tmp += (z1, z, z, z)
            res += tmp
          }
          else {
            loop.break()
          }
        }

        twoSumForFourSum(nums, target - z, i + 1, res, z1, z )
      }
    }
  }

  def fourSum(ns: Array[Int], target: Int): List[List[Int]] = {
    val res = new ListBuffer[ListBuffer[Int]]
    //异常情况
    if (ns == None || ns.size < 4) {
      return (for (l <- res) yield l.toList).toList
    }

    //默认排序
    var nums = for(n <- ns.sorted) yield n

    //临界情况
    val max = nums(nums.size - 1)
    val min = nums(0)
    if (4 * min > target || 4 * max < target) {
      return (for (l <- res) yield l.toList).toList
    }

    var first = new Breaks
    var second = new Breaks
    var thrid = new Breaks
    var loop = new Breaks

    var z = 0
    loop.breakable{
      for (i <- 0 to nums.size - 1) {
        z = nums(i)
        first.breakable {
          //避免重复,continue
          if (i > 0 && z == nums(i - 1)) {
            first.break()
          }


          //z太小
          if (z + 3 * max < target) {
            first.break()
          }


          //z太大
          if (4 * z > target) {
            first.break()
          }
        }

        //边界情况
        if (4 * z == target) {
          if (i + 3 < nums.size && nums(i + 3) == z) {
            val tmp = new ListBuffer[Int]
            tmp += (z, z, z, z)
            res += tmp
          } else {
            loop.break()
          }
        }

        threeSumFourSum(nums, target - z, i + 1, res, z)
      }
    }

    (for (l <- res) yield l.toList).toList
  }

  def main(args: Array[String]): Unit = {
    var a = Array(1, 0, -1, 0, -2, 2)
    println(fourSum(a, 0))
  }
}
阅读更多
想对作者说点什么? 我来说一句

18 votes 18 votes 18 votes 18 votes

2010年01月24日 10B 下载

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭